Shinobi Maze Lab
← Back to Journey

SHINOBI MAZE 誕生記
忍者 × ゴーストAI × 虹色CSS、1ファイルでパックマンを超えろ

PROLOGUE

パックマンの「食う&逃げる」を忍者でやる

ゲーム開発2日目、Edenyが選んだ次の挑戦はパックマン型の迷路ゲームだった。外部ライブラリなし、1ファイル完結、HTML5 Canvas だけで作る——という制約を自分に課した。

テーマは忍者。パックマンが持つ「食う&逃げる」という原初の面白さを、忍者の世界観でリスキンする。敵は4体の忍者ゴースト(Kage、Hana、Kiri、Tora)。プレイヤーが操るのも忍者だ。

外部ライブラリゼロの縛りは、Web Audio APIで効果音を全合成し、Gamepad APIでコントローラーに対応し、アトラクトモードまで実装することで試された。

BUILD

迷路・AI・音・演出を1ファイルに詰める

14×14の迷路と、その中心に住む4体のゴースト

マップは 14×14 の2次元配列で定義した。各セルを数値で分類し(0=通路、1=壁、2=ゲート、3=パワーペレット、4=ゴーストハウス)、中央にゴーストハウスを配置、4コーナーにパワーペレットを置く——パックマンの原典に倣った配置だ。

// 数値でセル種別を管理: 0=通路 / 1=壁 / 2=ゲート / 3=パワーペレット / 4=ゴーストハウス // 配列コピーだけでレベルをリセットできる

ゴーストAIは3つの状態で動く

ゴーストは scatter(散開)→ chase(追跡)→ frightened(怯え) の3ステートを持つ。散開時は各ゴーストが担当コーナーに向かい、追跡時はプレイヤーへ最短距離を取る。

方向の選択はBFS(幅優先探索)ではなくマンハッタン距離の最小化で実装した。精度よりも軽量さを優先した選択だ。4体が同時にゴーストハウスから出てくると詰まるため、退出タイミングを exitT: index * 50フレーム でずらしている。

効果音7種をすべてWeb Audio APIで合成

ドット取得音・パワーペレット音・死亡SE・レベルアップ音——これらを全て AudioContext + OscillatorNode + GainNode だけで作った。周波数・音色・音量・音程スライドを1関数で制御するミニシンセを作り、和音は currentTime + i * offset でタイミングをずらして forEach で鳴らすだけでアルペジオになる。

// 効果音の和音: forEach でタイミングをずらして鳴らすだけ // [440, 554, 659, 880] を 0.07秒ずつずらしてアルペジオに [440,554,659,880].forEach((f,i) => tone(f, 'sine', t+i*0.07, 0.13, 0.30));

Canvasで透明背景のマスコット、CSSで虹色タイトル

タイトル横の忍者マスコットは <canvas> に直接描いているが、背景を塗らないことで透明背景を実現している。CSSの background: transparent を指定するだけで、Canvasが浮いて見える。

虹色タイトルは -webkit-background-clip: text-webkit-text-fill-color: transparent の組み合わせ。background-size: 300% にして位置をアニメートすると、グラデーションが流れる虹になる。ゲームCanvasの外枠ボーダーも同じ手法で虹色に光らせた。

INSIGHT

1ファイルの可能性を知った日

TIP 01 Web Audio はユーザー操作後に初期化する
ブラウザはユーザー操作前に AudioContext を作れない。最初に音が鳴る瞬間に生成し、suspended 状態なら resume() を呼ぶ——このパターンが Web Audio の基本形になる。
TIP 02 Canvas 透明背景は「塗らない」だけ
背景を塗らなければ Canvas は透明のまま。HTML側で background: transparent を指定するだけでキャラクターが「浮いて」見える。マスコット表示に最適な手法だ。
TIP 03 ゴーストAIは3ステートで十分リアルになる
scatter / chase / frightened の3状態だけで、プレイヤーが「逃げなければならない」緊張感と「パワーペレットで逆転できる」爽快感の両方が生まれる。BFSなしでも成立する。
TIP 04 Gamepad のボタンはエッジ検出が必須
前フレームのボタン状態を保存して「現在=true かつ 前=false」の瞬間だけ発火させる。これがないと1回押しただけでゲームが連続スタートしてしまう。
「1ファイルHTML5の可能性」と「モノレポ+Vercelで一瞬公開できる快感」を身体で覚えた1日。外部依存ゼロで、これだけのものが作れる。

SUMMARY

パックマン型迷路ゲーム SHINOBI MAZE を1日でゼロから完成させた。Web Audio APIによる効果音7種の全合成、scatter/chase/frightenedの3ステートゴーストAI、Canvas透明マスコット、CSS虹色アニメーション、Gamepad API対応、アトラクトモードまで——全て外部ライブラリなしの1ファイルに詰め込んだ。1ファイルHTMLという制約が、逆に「何でも入れてやる」という発想を引き出した。

ALL UEFN × Verse Lab Log