【10】アリクイあくしょんコード解説 323行目〜

JavaScript
// スタート画面
function drawStartScreen() {
  ctx.fillStyle = "#222";
  ctx.fillRect(0, 0, canvas.width, canvas.height);
  ctx.fillStyle = "#fff";
  ctx.font = "32px sans-serif";
  ctx.textAlign = "center";
  ctx.fillText("ありくいアクション", canvas.width / 2, canvas.height / 2 - 100);
  ctx.font = "16px sans-serif";
  ctx.fillText("←→ 移動  | スペース ジャンプ |  ↑ 攻撃", canvas.width / 2, canvas.height / 2 + 50);
  ctx.fillText("スペースキーまたは画面をタップでスタート", canvas.width / 2, canvas.height / 2 + 150);
  ctx.font = "12px sans-serif";
  ctx.fillText("© 2025 たかまる", canvas.width / 2, canvas.height / 2 + 250);
}

// ゲームオーバー画面
function drawGameOver() {
  ctx.fillStyle = "rgba(0,0,0,0.7)";
  ctx.fillRect(0, 0, canvas.width, canvas.height);
  ctx.fillStyle = "#fff";
  ctx.font = "bold 48px sans-serif";
  ctx.textAlign = "center";
  ctx.textBaseline = "middle";
  ctx.fillText("ゲームオーバー", canvas.width / 2, canvas.height / 2 - 20);
  ctx.font = "24px sans-serif";
  ctx.fillText("スペースキーまたは画面をタップで再スタート", canvas.width / 2, canvas.height / 2 + 40);
}

function mainLoop() {
  if (gameStarted) return;
  drawStartScreen();
  requestAnimationFrame(mainLoop);
}
mainLoop();
イカクくん
イカクくん

fillは塗りつぶしだったよね!

たかまる
たかまる

そうそう!
そしてRectはRectangle(長方形)だったよね!
.fillRect(x座標, y座標, width, height);
が基本形だよ。

fillText

ctx.fillText("ありくいアクション", canvas.width / 2, canvas.height / 2 - 100);
イカクくん
イカクくん

– 100がついてるけど、どうなるの?

たかまる
たかまる

中央から上に100ずれるよ。

イカクくん
イカクくん

ここで幅が中央に指定されてるなら、
ctx.textAlign = “center”;
この中央寄せの指示って必要ないんじゃないの?

textAlign(横方向)

たかまる
たかまる

テキストにも基準点があって、
デフォルトは左下なんだ。

イカクくん
イカクくん

ってことは、textAlign = “center”;がないと、
中央より右寄りで若干上に表示されてしまうのか。

textBaseline(縦方向)

イカクくん
イカクくん

んじゃ縦方向も中央寄せにしたい場合どうしたらいいの?

たかまる
たかまる

textBaseline = “middle”;
だから、今回の場合だと
ctx.textBaseline = “middle”;
でOK!

ループ

function mainLoop() {
  if (gameStarted) return;
  drawStartScreen();
  requestAnimationFrame(mainLoop);
}
mainLoop();

このコードは、スタート画面(タイトル画面)をアニメーションループで表示し続けるための基本構造。

ざっくり言うと:

  • ゲームが始まったら実行を中断して抜ける。
    drawStartScreen()requestAnimationFrame() は実行されない)
  • ゲームが始まっていなければ、
  • 毎フレーム drawStartScreen() を呼び出して描画
  • requestAnimationFrame(mainLoop) で繰り返す

return

関数の中で return を書くと、その行で関数の実行を中断して抜ける。

戻り値を返すときにも使うが、今回は「処理の終了」が目的。

書き方意味
return;関数の処理をそこで終了
return 値;関数の結果として値を返す
if (...) return;条件が合えば関数を早く抜ける

requestAnimationFrame(関数名);

「次の画面更新の直前に、この関数を呼んで!」とブラウザにお願いする関数。
ブラウザは画面を 1 秒間に 60 回くらい更新(リフレッシュ)している。(= 約60FPS)

✅ 実行の流れ

  1. mainLoop() が実行される
  2. gameStartedfalse なので drawStartScreen() が実行される
  3. 次のフレームで mainLoop() が再度呼ばれる
  4. …繰り返し(60FPS)
  5. gameStarted = true になると、return で描画を停止
イカクくん
イカクくん

elseは使わないの?

たかまる
たかまる

else がなくても処理が分かれる理由は、
if の中で関数が途中終了するから。
あと{}で囲ってないから、ifが適用されるのは
if (gameStarted) return;
の、1行のみだよ。

// A: returnで早期終了するパターン
if (gameStarted) return;
drawStartScreen();
requestAnimationFrame(mainLoop);

// B: elseを使うパターン
if (gameStarted) {
  return;
} else {
  drawStartScreen();
  requestAnimationFrame(mainLoop);
}

どちらも動作は同じ

function mainLoop() {
  if (gameStarted) return; // この行はゲームが始まったら実行を中断するだけの指示
  drawStartScreen();
  requestAnimationFrame(mainLoop);
}
// なので、ゲームが始まっていない時は↓と同じってこと
function mainLoop() {
  drawStartScreen();
  requestAnimationFrame(mainLoop);
}

mainLoop();

function mainLoop() {
  if (gameStarted) return;
  drawStartScreen();
  requestAnimationFrame(mainLoop);
}
mainLoop(); // ←これのこと!
たかまる
たかまる

これは単純に関数の 呼び出し(実行)だよ。

書き方意味
mainLoop();mainLoopを1回だけ実行する
requestAnimationFrame(mainLoop);次のフレームでまた実行して…を繰り返す
たかまる
たかまる

今回はここまで。
次のページでゲーム開始の処理を解説していくよ。

コメント

タイトルとURLをコピーしました