ソースコード解説・目次

CHAPTER 03 · 全23項目

画面と状態遷移

タイトル、プレイ、ミス、クリア、ゲームオーバーを状態で管理します。

主な参照先:state / stateT / setState / setPaused

画面名を1つの変数で表す

game.html · L837–839ソースを見る ↗
let state = "title";       // title | play | dying | clear | gameover
let stateT = 0;
let paused = false;
状態起きること次の状態
title開始入力を待つstartGame() で play
play移動・射撃・衝突を処理被弾で dying、全滅で clear、侵入で gameover
dyingミスの演出を待つ1.15秒を超えると残機に応じて復帰か終了
clearクリア演出を表示1.6秒を超えると次のウェーブを作って play
gameover結果を表示0.6秒を超えてから開始入力で再挑戦

状態の切り替えと経過時間

game.html · L872–875ソースを見る ↗
function setState(s) {
  state = s; stateT = 0;
  cvs.style.cursor = (s === "play" && !paused) ? "none" : "pointer";
}
game.html · L1791–1805ソースを見る ↗
function update(dt) {
  stateT += dt;
  updateCommon(dt);
  if (state === "play") {
    updatePlay(dt);
  } else if (state === "dying") {
    if (stateT > 1.15) {
      if (lives > 0) { player.alive = true; player.inv = 2; setState("play"); if (saucer) saucerSoundStart(); }
      else gameOver();
    }
  } else if (state === "clear") {
    // 操作を止めずに次のウェーブへ。押しっぱなしの射撃・移動キーもそのまま引き継ぐ。
    if (stateT > 1.6) { wave++; makeWave(); setState("play"); }
  }
}

stateT は現在の状態になってからの秒数です。切り替えるたびに0へ戻すことで、「ミスしてから何秒待つか」をその状態だけの条件として書けます。updateCommon() は星やパーティクルなどの共通処理、updatePlay() は戦闘専用の処理です。clear では入力を待たず、1.6秒を超えたフレームで wave++・makeWave()・setState("play") を続けて実行し、次のウェーブを始めます(ウェーブクリアと次のウェーブ)。dying からプレイに戻る時は、ミスした時に hitPlayer() が止めた円盤の効果音を、円盤がまだ画面にいれば鳴らし直します。

ポーズは別のフラグ

paused は state と独立しています。プレイ中またはミスの演出中に一時停止しても、どちらの状態だったかは失われません。setPaused(true) は押しっぱなしの入力を解放し、音の予約を止めます。