Skip to content

第07回 調整・デバッグ・安定化

前回: 第06回 ステートマシン入門 / 次回: 第08回 最終仕上げと発表

前回の振り返り

敵やギミックで失敗条件を追加しました

  • Enemy 構造体で敵の情報をまとめました
  • 敵を更新し、画面に描画しました
  • プレイヤーと敵の衝突を矩形判定で確認しました
  • 敵に当たったら GameOver になり、リトライできるようにしました
  • 今回は、提出前に重大なバグを減らします

今回の目的

作品を最後まで遊べる状態に安定させる

  • 再現手順を記録してバグを切り分ける
  • 進行不能バグを優先して修正する
  • デバッグ表示で位置、速度、状態を確認する
  • 発表に向けて、実装意図を説明できるようにする

今回の授業内容

調整・デバッグ・安定化

  • 提出前に確認するバグの種類
  • 再現手順の書き方
  • F1 によるデバッグ表示切り替え
  • 位置、速度、接地状態、ゲーム状態の確認
  • 修正優先度の判断
  • 発表準備メモの作成

壊れにくくする

完成度は 最後の確認で変わります

直す順番を決める

確認するバグ

最低限ここは確認する

  • 壁や床へのめり込み
  • 連続ジャンプの誤動作
  • 画面外へ落下した後の復帰
  • ゴール判定の取りこぼし
  • 敵に当たってもゲームオーバーにならない
  • リトライ後に速度や敵位置が初期化されない
  • 画像未読込時にゲームが止まる

再現手順とは

バグをもう一度起こすための手順

  • どのステージで起きたか

  • どの位置から始めたか

  • どのキーを押したか

  • 何が起きるはずだったか

  • 実際に何が起きたか

  • 再現できないバグは、原因を探すのが難しくなります

再現手順の例

現象を短く具体的に書く

  • 曖昧な「変になる」ではなく、起きたことを書きます
  • 修正後は、同じ手順でもう一度確認します
text
現象:
右端の足場に着地すると、プレイヤーが床へ少しめり込む。

再現手順:
1. タイトルでSPACEを押して開始する。
2. 3つ目の足場まで進む。
3. 右端ぎりぎりでZジャンプする。
4. 着地時にプレイヤーの足が床へ入る。

期待:
床の上で止まる。

デバッグ表示用の変数

F1で表示を切り替える

  • 常に表示すると画面が見づらくなります
  • F1 を押した瞬間だけ切り替えるため、前フレームの入力状態を保存します
  • 完成版では、不要なデバッグ表示を消すか非表示にします
cpp
class Game
{
private:
    bool debugVisible = false;
    bool previousF1 = false;

    void UpdateDebugToggle();
    void DrawDebug() const;
};

F1トグル処理

押しっぱなしで連続切替しないようにする

  • 現在の F1 入力を調べます
  • 今回押されていて、前回押されていないときだけ切り替えます
  • 最後に現在の状態を previousF1 へ保存します
cpp
void Game::UpdateDebugToggle()
{
    bool currentF1 = CheckHitKey(KEY_INPUT_F1) != 0;

    if (currentF1 && !previousF1)
    {
        debugVisible = !debugVisible;
    }

    previousF1 = currentF1;
}

デバッグ表示

位置、速度、状態を画面に出す

  • x, y でプレイヤー位置を確認します
  • vx, vy で速度を確認します
  • onGround で接地判定を確認します
  • gameState で現在状態を確認します
cpp
void Game::DrawDebug() const
{
    if (!debugVisible) return;

    DrawBox(8, 72, 265, 154, GetColor(0, 0, 0), TRUE);

    DrawFormatString(14, 80, GetColor(255, 255, 255),
        L"x:%d y:%d vx:%d vy:%d",
        player.x, player.y, player.vx, player.vy);

    DrawFormatString(14, 100, GetColor(255, 255, 255),
        L"onGround:%d camera:%d",
        player.onGround ? 1 : 0, cameraX);

    DrawFormatString(14, 120, GetColor(255, 255, 255),
        L"state:%d csv:%d",
        gameState, stage.IsLoadedFromCsv() ? 1 : 0);
}

UpdateとDrawへ組み込む

毎フレーム更新し、必要なときだけ描く

  • UpdateDebugToggle は、どの状態でも使えるように先に呼びます
  • DrawDebug はプレイ画面の最後に呼びます
  • デバッグ表示はゲームの判定を変えないようにします
cpp
void Game::Update()
{
    UpdateDebugToggle();

    switch (gameState)
    {
    case Title: UpdateTitle(); break;
    case Playing: UpdatePlaying(); break;
    case GameClear:
    case GameOver: UpdateResult(); break;
    }
}

void Game::DrawPlaying() const
{
    stage.Draw(cameraX);
    DrawEnemy();
    DrawPlayer();
    DrawHud();
    DrawDebug();
}

コードの解説

見えない情報を一時的に見えるようにする

  1. バグが起きる場面を再現する
  2. F1 でデバッグ表示を出す
  3. 位置、速度、接地状態、ゲーム状態を確認する
  4. 期待と違う値を探す
  5. 関係する処理を修正する
  6. 同じ再現手順でもう一度確認する

修正優先度

直す順番を決める

  1. 進行不能バグ 起動しない、クリアできない、リトライできない
  2. 操作性に直結するバグ めり込み、連続ジャンプ、極端なすり抜け
  3. ルールの不整合 敵に当たっても失敗しない、ゴール判定が安定しない
  4. 見た目の不整合 画像位置、HUD、色、演出
  5. 追加改善 コイン、演出、追加ステージ

実習1: バグを抽出する

重大なものから3件まで選ぶ

  1. 自分の作品を最初から最後までプレイする
  2. 気になった不具合をリスト化する
  3. 再現手順を書く
  4. 進行不能に近いものから優先順位を付ける
  5. 今日直すものを3件までに絞る

実習2: デバッグ表示を使って修正する

値を確認しながら直す

  1. F1 デバッグ表示を実装する
  2. バグの再現手順を実行する
  3. 位置、速度、接地状態、ゲーム状態を確認する
  4. 原因になっていそうな処理を修正する
  5. 同じ手順で再確認する
  6. 修正結果をメモする

発表準備メモ

実装意図を短くまとめる

  • 作品タイトル
  • どんな体験にしたかったか
  • 実装で工夫した点
  • 調整した数値と理由
  • 一番苦労したバグ
  • 最終回までに直したい点

今日の最低到達

最終回へ進める品質にする

  • 作品を最初から最後までプレイできる
  • 重大バグを確認し、優先順位を付けている
  • 1件以上のバグについて再現手順を書いている
  • デバッグ表示で値を確認できる
  • 発表準備メモの下書きがある

今回のまとめ

提出前の安定化を進めました

  • バグの再現手順を書きました
  • 修正優先度を決めました
  • F1 で切り替えるデバッグ表示を追加しました
  • 位置、速度、接地状態、ゲーム状態を確認しました
  • 次回は、最終確認を行い、作品を発表します

おつかれさまでした!

次回予告 第08回 最終仕上げと発表

作ったものを 説明できる形にします