全画面Canvasゲーム「環 -RING-」の作り方|ネオングローとFullscreen APIで作るおしゃれゲーム

新作の環 -RING-は、Canvasで描いたネオンの環の上を彗星が巡り、宝石に重なった瞬間にタップするワンボタンゲームだ。全画面表示に対応し、HTML・CSS・JavaScriptの単一ファイルで動く。この記事では「おしゃれなゲーム」を支える技術を解説する。

「美しさ」の正体は4つのテクニック

1. ネオン発光はshadowBlurで作る

環や彗星の発光は、画像を使わずCanvasのshadowColorとshadowBlurだけで表現している。線や図形を描く直前に影色と滲み量を指定するだけで、それらしいグローになる。ただしshadowBlurは描画コストが高いので、毎フレーム使うのは数か所に絞り、使い終わったら必ず0に戻すのがパフォーマンスの要点だ。

ctx.strokeStyle = ringCol;
ctx.shadowColor = ringCol;
ctx.shadowBlur  = 16;
ctx.stroke();
ctx.shadowBlur  = 0;  // 使い終わったら即リセット

2. 色はスコアと一緒に巡らせる

環の色は固定ではなく、HSL色相をヒットのたびに7度ずつ回している。プレイが進むほど青→紫→赤→金と世界の色が変わり、スコアが伸びている実感が視覚に直結する。RGBではなくHSLで持つと「色を回す」処理が1行で済む。

3. 余韻は「トレイル」と「パーティクル」

彗星は単なる点ではなく、直近16フレームの座標を配列に残して、古いものほど小さく薄く描いている。これだけで「尾を引く彗星」になる。ヒット時は宝石の位置から粒子を放射し、速度を毎フレーム0.97倍に減衰させる。この摩擦係数が0.9だと爆発が硬く、0.99だと間延びする。質感は係数1つで決まる。

4. UIはガラス、ゲームは宇宙

タイトルとリザルトはCanvasに描かず、HTMLのオーバーレイにbackdrop-filter:blurをかけたガラス風パネルにした。背景では常にCanvasの星空が流れ続けるので、止め絵のメニューでも世界が生きて見える。文字は極細ウェイト+広めのletter-spacingにすると一気に「おしゃれ」に寄る。

全画面対応(Fullscreen API)の実装

全画面化はゲームの枠divに対してrequestFullscreenを呼ぶだけだが、実戦では3つの注意点がある。第一に、Safari系はwebkitプレフィックス版しかない環境があるため両対応する。第二に、iPhoneのSafariのように要素の全画面化に未対応のブラウザがあるので、APIの存在を確認してボタンごと隠す。第三に、全画面の出入りで描画領域のサイズが変わるため、fullscreenchangeイベントでCanvasを再フィットさせる。

var canFs = false;
if (F.requestFullscreen) { canFs = true; }
if (F.webkitRequestFullscreen) { canFs = true; }
if (!canFs) { fsBtn.style.display = 'none'; }

document.addEventListener('fullscreenchange', function(){
  setTimeout(fit, 80);  // サイズ確定を待ってCanvasを再フィット
});

あわせてdevicePixelRatioでCanvasの実ピクセルを拡大しておくと、Retina系ディスプレイでも線がぼやけない。「おしゃれなゲーム」の印象は、実はこの解像度対応で大きく変わる。

ゲームデザイン:円周上の判定ロジック

彗星と宝石はどちらも角度(ラジアン)で管理している。タップ判定は2つの角度差を-πからπに正規化した絶対値で測るだけだ。「素通り」の検出は、進行方向に符号を揃えた角度差が判定窓を内側から外側へ越えた瞬間をミスとする。回転方向の反転(13%)があるため、符号処理を雑にするとここがバグの巣になる。

function wrapPi(x){
  while (x >  Math.PI) { x -= Math.PI * 2; }
  while (x < -Math.PI) { x += Math.PI * 2; }
  return x;
}
var d = Math.abs(wrapPi(a - t));      // タップ時の判定
if (d <= win * 0.34) { /* PERFECT */ }
else if (d <= win)   { /* HIT */ }
else                 { /* MISS */ }

難易度は「速度+0.045/ヒット」「判定窓がスコアに応じて0.45→0.21ラジアンへ縮小」「13%で回転反転」の3変数だけで作っている。変数が少ないほど調整は速い。

Claude Codeへの依頼プロンプト例

全画面対応の美しいワンボタンゲームを単一HTMLで作って。

コンセプト: 宇宙。環を巡る彗星を、宝石の上でぴったりタップ
- Canvas描画、ネオングロー(shadowBlur)、彗星トレイル、ヒット時パーティクル
- ヒットごとにHSL色相が回り、世界の色が変わる
- PERFECT判定(窓の中心34%)で2点、通常1点、ミス3回で終了
- Fullscreen API対応(webkitプレフィックス両対応、未対応ならボタン非表示)
- devicePixelRatio対応でRetinaでも線がくっきり
- タイトル/リザルトはbackdrop-filterのガラス風オーバーレイ

制約: 音声・外部ライブラリ禁止、ES5、クラス名rng-、
アンパサンドとバッククォート禁止(WordPress埋め込み用)

まとめ

「おしゃれ」は才能ではなく、グロー・色相回転・トレイル・ガラスUIという再現可能な技術の積み重ねだった。ゲームロジック自体は角度差の比較1つで、コードの大半は見た目に使っている。ミニゲームこそ、ロジックより演出に行数を割くと印象が激変する。

ゲーム本体は環 -RING-|全画面で遊べる美しい無音ブラウザゲームから。無音ゲーム第1弾の制作記は無音ゲーム「静寂道場」の作り方へ。