状態別処理の考え方とプログラム

スタート画面とゲーム画面、ゲームオーバー画面など、状態によって処理(実行する関数)を変えることにより、効率のよいプログラムを作成できる。では、具体的にどのようなプログラムを作ればいいかを考える。

考え方

例えばスタート画面を表示する処理では次のように考える。

《解説》

実際のプログラム

上記のフローチャートのようにスタート画面処理を作成すると、次のようになる。

プロトタイプ宣言の追加

// プロトタイプ宣言
LRESULT CALLBACK WinProc(HWND, UINT, WPARAM, LPARAM);   // Windows関数
BOOL InitApp(HINSTANCE, int);                           // ユーザー関数
HRESULT InitDX8(void);                                  // DirectX8初期化処理
void ReleaseD3D(void);                                  // DirectX8開放処理
void ResetWindow(void);                                 // ウィンドウ再生成処理
BOOL UpdateFrame(void);                                 // ゲームメイン処理
void StartInit(void);                                   // スタート画面初期化処理
void StartFrame(void);                                  // スタート画面処理

スタート画面初期化関数、スタート画面処理関数の追加

//-----------------------------------------------------------------------------
// 関数名 : StartInit()
// 機能概要: スタート画面初期化処理
//-----------------------------------------------------------------------------
void StartInit(void)
{
    //--------------------------------------------------- 各変数の初期化

    //--------------------------------------------------- フレームナンバーセット
    g_FrameNo = START_FRAME;

}

//-----------------------------------------------------------------------------
// 関数名 : StartFrame()
// 機能概要: スタート画面処理
//-----------------------------------------------------------------------------
void StartFrame(void)
{
    // スタート画面用の背景画像をバックバッファに転送

    // タイトル画像をバックバッファに転送

    // START画像(Push Return Key to Start)をバックバッファに転送

    // リターンキーが押されたら、ゲーム開始
    if ( gl_KeyTbl[VK_RETURN] & 0x80 ) g_FrameNo = GAME_INIT;

}

《解説》

状態別処理(UpdateFrame関数)の修正

スタート画面初期化処理関数(StartInit関数)、スタート画面処理(StartFrame関数)を作成したら、それらが実行されるように状態別処理関数(UpdateFrame関数)を次のように修正する。

//-----------------------------------------------------------------------------
// 関数名 : UpdateFrame()
// 機能概要: ゲームメイン処理
//-----------------------------------------------------------------------------
void UpdateFrame(void)
{

    /* 現在のキー情報を取得 */
    if ( !GetKeyboardState(gl_KeyTbl) ) {
        MessageBox(hWnd, "キー情報の取得に失敗", "ERROR", MB_OK);
        return (FALSE);
    }

    /* 処理の振り分け */
    switch ( g_FrameNo ) {
        case START_INIT:
            // スタート画面を表示する前に実行する初期化関数を実行
            StartInit();
        case START_FRAME:
            // スタート画面表示処理関数を実行
            StartFrame();
            break;
        case GAME_INIT:
            // ゲーム画面を表示する前に実行する初期化関数を実行
        case GAME_FRAME:
            // ゲーム画面表示処理関数を実行
            break;
        default:
            MessageBox(hWnd, "g_FrameNoの値が例外です。", "ERROR", MB_OK);
            return (FALSE);
    }

    /* フリップ処理 */

    return (TRUE);
}

《解説》

※以上の修正を行ったらビルドを行い、プログラムが正常に動くかどうかを確かめる
(一切の描画を行っていないため、見た目は何も変わらない)。


BACK(キーボードの状態を取得する(WindowsAPI)) NEXT(練習問題)