第7章 キー操作を制御する

7−3 ゲーム開始直後に弾を撃たないようにするには?

現在のプログラムは、ゲーム開始時、自キャラから弾が発射されてしまう。これは、スタート画面からスペースキーを押してゲーム画面に切り替わったとき、同じくスペースキーの入力を検地してしまうためである。
これを防ぎ、ゲーム開始時に弾が発射されないようにするにはどうすればよいだろうか?

  1. START選択時、START画像を一定時間点滅させてからゲームを開始する
    (その間にスペースキーを離すはず)
  2. ゲーム開始直後は弾を打てないようにする
    (自キャラを点滅、登場のアニメーション、READY GOなどの文字列表示など)
  3. その他・・・

今回はサンプルとして、ゲーム開始後3秒は動けないようなプログラムを作成する。

(a) ゲーム開始直後状態を作成する

ゲーム処理は現在「ゲーム開始前初期化処理(GAME_INIT)」と「ゲーム処理(GAME_FRAME)」の2つの状態を持っているが、新たに「ゲーム開始直後処理(GAME_READY)」を追加する。プログラムは長くなるが、状態別に関数を作成することにより、改造のしやすいプログラムを作ることができる。

まず、common.hを次のように修正する。

//=============================================================================
// プロジェクト内で共通に読み込まれるヘッダ・ファイル
//=============================================================================
  ・
  ・
  ・
//-----------------------------------------------------------------------------
// マクロ定義
//-----------------------------------------------------------------------------
/* ゲーム進行状況判断用 */
#define START_INIT      0
#define START_FRAME     1
#define GAME_INIT       10
#define GAME_READY   11
#define GAME_FRAME      12

/* キャラクタ情報用 */
#define DIRECTION_MAX   5       // キャラクタの向き情報の最大数
#define ANIMATION_MAX   5       // キャラクタのアニメーション数の最大
#define ANIMATION_TIME  500     // キャラクタアニメーションの単位(ミリ秒)
#define READY_TIME   3000   // READY状態の時間(ミリ秒)
  ・
  ・
  ・

※GAME_INITとGAME_FRAMEの間にGAME_READYが追加された
※READY状態は3秒(3000ミリ秒)にセットした

次に、GAME_INIT処理の次はGAME_READY処理が行われるよう、WinMain.cppのUpdateFrame関数を修正する。

//-----------------------------------------------------------------------------
// 関数名 : UpdateFrame()
// 機能概要: 画面更新処理
//-----------------------------------------------------------------------------
static void UpdateFrame(HWND hWnd)
{
  ・
  ・
  ・
    /* 処理の振り分け */
    switch (g_FrameNo)
    {
        case START_INIT:
            StartInit(hWnd);
        case START_FRAME:
            StartFrame(hWnd);
            break;
        case GAME_INIT:
            GameInit(hWnd);
        case GAME_READY:
            GameReady(hWnd);
            break;
        case GAME_FRAME:
            GameFrame(hWnd);
            break;
        default:
            OutputDebugString("g_FrameNoの値が例外です。\n");
    }
  ・
  ・
  ・

(b) ゲームREADY処理を追加する

ゲームREADY処理は、Game.cpp内に作成する。Game.cpp内の任意の場所(GameInit関数の下が見やすい?)に、以下の関数を作成する。

Game.cpp
//-----------------------------------------------------------------------------
// 関数名 : GameReady()
// 機能概要: ゲーム開始時処理
//-----------------------------------------------------------------------------
void GameReady(HWND hWnd)
{
    ScreenOut();  // 描画処理
    /* 3秒経ったらゲーム処理に移行する */
    if ( nowTickCount - MyChar.AnimeTime >= READY_TIME )
    {
        MyChar.AnimeTime = nowTickCount;
        g_FrameNo = GAME_FRAME;
        return;
    }

}

※ScreenOut関数を使いまわしていることに注目!!
※この関数はUpdateFrame関数からも呼ばれるため、プロトタイプ宣言をGame.h内で行うこと!!

Game.h
//-----------------------------------------------------------------------------
// Game.cppの関数のうち、他のソースで利用される関数のプロトタイプ宣言
//-----------------------------------------------------------------------------
void GameInit(HWND);
void GameFrame(HWND);
void GameReady(HWND);

次に、初期化処理後にこの関数を実行するよう、GameInit関数を次のように修正する。

//-----------------------------------------------------------------------------
// 関数名 : GameInit()
// 機能概要: スタート処理初期化
//-----------------------------------------------------------------------------
void GameInit(HWND hWnd)
{
    //------------------------------------------------------- 各変数の初期化
    /* 自キャラ(カーソルキーで移動) */
    StatusInit(&MyChar, 0, 0, 40, 40, 310, 230, 2, 2, 5, STOP, nowTickCount, 5, 0, 1);
    /* 自ショット(スペースキーで発射) */
    StatusInit(&MyShot, 392, 64, 398, 80, 0, 0, 0, 3, 1, STOP, nowTickCount, 1, 0, 0);

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

}

以上の修正を行い、コンパイル&実行すると、ゲーム開始直後から3秒間はキャラクタが動かなくなる。これにより、結果的にゲーム開始時に弾が出なくなる

※このGameReady関数を作りこみ、開始直後にアニメーションを行わせるなどの処理を作成するとよい。

確認(必須問題)

7-3(a)〜7-3(b)の修正を行い、ゲーム開始から3秒間はキャラクタが移動しないことを確認する。

[ 実行結果サンプル ]


[ TOP ]