Appearance
第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();
}コードの解説
見えない情報を一時的に見えるようにする
- バグが起きる場面を再現する
F1でデバッグ表示を出す- 位置、速度、接地状態、ゲーム状態を確認する
- 期待と違う値を探す
- 関係する処理を修正する
- 同じ再現手順でもう一度確認する
修正優先度
直す順番を決める
- 進行不能バグ 起動しない、クリアできない、リトライできない
- 操作性に直結するバグ めり込み、連続ジャンプ、極端なすり抜け
- ルールの不整合 敵に当たっても失敗しない、ゴール判定が安定しない
- 見た目の不整合 画像位置、HUD、色、演出
- 追加改善 コイン、演出、追加ステージ
実習1: バグを抽出する
重大なものから3件まで選ぶ
- 自分の作品を最初から最後までプレイする
- 気になった不具合をリスト化する
- 再現手順を書く
- 進行不能に近いものから優先順位を付ける
- 今日直すものを3件までに絞る
実習2: デバッグ表示を使って修正する
値を確認しながら直す
F1デバッグ表示を実装する- バグの再現手順を実行する
- 位置、速度、接地状態、ゲーム状態を確認する
- 原因になっていそうな処理を修正する
- 同じ手順で再確認する
- 修正結果をメモする
発表準備メモ
実装意図を短くまとめる
- 作品タイトル
- どんな体験にしたかったか
- 実装で工夫した点
- 調整した数値と理由
- 一番苦労したバグ
- 最終回までに直したい点
今日の最低到達
最終回へ進める品質にする
- 作品を最初から最後までプレイできる
- 重大バグを確認し、優先順位を付けている
- 1件以上のバグについて再現手順を書いている
- デバッグ表示で値を確認できる
- 発表準備メモの下書きがある
今回のまとめ
提出前の安定化を進めました
- バグの再現手順を書きました
- 修正優先度を決めました
F1で切り替えるデバッグ表示を追加しました- 位置、速度、接地状態、ゲーム状態を確認しました
- 次回は、最終確認を行い、作品を発表します