鬼門(Kimon)

鬼門(Kimon)

Next.jsReactTypeScriptTailwind CSSshadcn/uiSupabasePostgreSQLVercel

概要

鬼門は、日本語を学ぶ人のための聞き取りと読みのゲームです。曲と難易度を選ぶと、YouTubeの動画が流れ、歌詞が一行ずつ表示されます。空欄のある行が来ると動画が止まり、四つの中から正しい言葉を選びます。間違いの選択肢は正解と同じ読みなので、音だけでなく漢字を知っていないと答えられません。

鬼門とは、日本の言い伝えで鬼や霊が出入りするとされる北東の方角のことです。プレイヤーは登録時に選んだ幽霊として遊びます。難易度は鬼の位で、妖怪、鬼、鬼神の三つ。位が上がるほど、曲の中の空欄が増えます。雰囲気は怖さよりいたずら心が中心で、日本語の文字が常に最優先です。見出しには筆文字のフォントを使い、歌詞と答えには読みやすさを重視したBIZ UDPゴシックを使っています。

主な機能

  • 曲のカタログ:ジャンル(アニメ、J-POP、シティポップ、ボカロ、演歌)や検索、手作りのコレクションから曲を探せます。カード表示と表表示を切り替えられます。
  • ゲーム画面:動画、カラオケ風の歌詞、四枚の答えカード。マウスか1〜4のキーで選べます。
  • 言葉の意味:答えた後、横のパネルで各選択肢の意味を確認でき、Jishoのページにも飛べます。間違いもそのまま学びになります。
  • プロフィール:過去のプレイ、ベストスコア、お気に入りの曲、実績。
  • WaniKani連携:WaniKaniで勉強している人はアカウントをつなぐと、自分のレベルと覚えた漢字がプロフィールに表示されます。
  • 曲のリクエスト:プレイヤーは曲をリクエストし、短いメッセージのやりとりで私と相談できます。

仕組み

ゲーム。 ゲーム画面は、待機、再生、問題、終了の四つの段階を持つ小さなステートマシンで動いています。YouTubeプレーヤーに再生、一時停止、シークのタイミングを伝えます。プレーヤーは一度に一つの命令しか処理できないため、各命令は前の命令が終わるのを待ち、素早く次の命令が来た場合は前の命令を取り消します。シークの遅れを補うため動画は0.25秒早く止まり、問題が出る前に答えの言葉が聞こえることはありません。

サーバー。 アプリはVercel上のNext.js(App Router)で動いています。ページはSupabaseからデータを読むサーバーコンポーネントで、プレイの保存やお気に入りの追加などの書き込みはすべて、サーバー側で入力を確認するサーバーアクションです。プレイの保存に失敗した場合はブラウザに残り、次の訪問時に再送されます。

データベース。 Supabaseにカタログ、プレイヤー、プレイ記録を保存しています。行レベルセキュリティにより、カタログは誰でも読めますが、プレイヤーは自分の行しか読み書きできません。データベースのトリガーが、プレイの保存時に実績を与え、開いている曲リクエストの数を制限し、一度選んだ幽霊を変えられないようにしています。WaniKaniのトークンはSupabase Vaultに暗号化して保存され、読み出せるのはサーバーだけです。

曲の追加。 同期歌詞とタイムスタンプは、LRCLIBから取得してSQLとして書き出すスクリプトで用意します。問題は手作業で作ります。一行に一つの空欄、選択肢は実在する四つの言葉、そして問題ごとの位。別のスクリプトが辞書で全選択肢を確認し、間違いを見つけます。

デザイン

見た目は「インク・ブルータリズム」。太い黒の枠線、はっきりした影、そして伝統的な日本の色から選んだ少数の色を使っています。主な操作には朱、選択中のものには藍。パブリックドメインの浮世絵がページを飾り、和紙の質感や刷りの効果はCSSで描いています。ページの切り替えには墨の筆のトランジションを使い、すべてのアニメーションは「視差効果を減らす」設定に従います。

ギャラリー

鬼門(Kimon): browse
鬼門(Kimon): rank
鬼門(Kimon): gameplay
鬼門(Kimon): results