第14章 複数のキャラクタを制御する(シューティング向け?)

14-3 一定時間ごとに敵キャラをランダムに出現させる

ゲームが始まると、一定時間ごとに敵キャラが現れるようなプログラムを作成する。現れるキャラのタイプは0から4までのランダムで決定する。

1. 乱数ジェネレータの初期化

このゲームではランダム関数を使用するため、ゲームを実行するたびにランダムに発生する数を変えるため、乱数ジェネレータを初期化する。この処理はプログラム実行時に1度だけ行えばいいため、ゲームループに入る前に行う。

//=============================================================================
//	ウィンドウメイン関数(WinMain)
//=============================================================================
int WINAPI WinMain(HINSTANCE hThisInst, HINSTANCE hPrevInst, LPSTR lpszArgs, int nWinMode)
{
    HWND    hWnd;
    MSG     msg;

    /* 表示するウィンドウの定義、登録、表示 */
    if (!(hWnd = InitApp(hThisInst, nWinMode)))
        return FALSE;

    /* Direct Draw Object の初期化 */
    if (InitializeDraw(hWnd) != DD_OK)
        return FALSE;

    /* 乱数ジェネレータを初期化 */
    srand(time(NULL));

    /* ゲーム・ループ */
    while (TRUE)
    {
        ・
        ・
        ・

※time関数を実行するには、time.hをインクルードしなければならない(common.hがベスト?)

2. 敵キャラが現れるタイミングを決める

一定時間ごとに敵キャラを表示させるため、時間制御を行わなければならない。game.cppで次のように宣言する。

//=============================================================================
//	Game処理関係の自作関数群
//=============================================================================
#include "common.h"

//-----------------------------------------------------------------------------
// マクロ(ソース内でしか使わないもの)
//-----------------------------------------------------------------------------
#define ENEMY_INTERVAL	500	// 敵キャラが出現するタイミング

//-----------------------------------------------------------------------------
// プロトタイプ宣言(ソース内でしか使わないもの)
//-----------------------------------------------------------------------------
static void SetEnemy(void);
static void BackDraw(void);
static void CharDraw(void);
static void CharMove(void);
static void ScreenHitCheck(void);
static void CharHitCheck(void);
static void MyCharaStatusInit(MYCHARASTATUS *, int, int, int, int, int, int);
static void MyCharaStatusStargeInit(MYCHARASTATUS *, int, int, int, int);
static bool HitCheck(RECT, RECT);
static void CreateHitRect(RECT *, int, int, RECT *);

//-----------------------------------------------------------------------------
// ゲーム処理用グローバル変数
//-----------------------------------------------------------------------------
static int StargeNumber;                        // ステージ数制御用
static DWORD EnemyTime;	// 敵キャラ出現制御用
static DWORD EndTime;                           // ゲームクリア・ゲームオーバー時の時間制御用
static MYCHARASTATUS MyChara;                   // 自キャラのステータス
static ENEMYSTATUS Enemy[ENEMY_MAX];            // 敵キャラのステータス
static ENEMYBLTSTATUS EnemyBlt[ENEMYTYPE_MAX];  // 敵キャラ画像データ
・
・
・

※マクロはcommon.hにおいても問題はない

3. 初期化処理

敵キャラの出現タイミングは、ステージが始まる瞬間を0とし、そこから一定時間ごとでなければならない。そのため、ステージ別初期化処理で初期化を行う。

//-----------------------------------------------------------------------------
// 関数名 : GameStargeInit()
// 機能概要: ステージ毎初期化処理
//-----------------------------------------------------------------------------
void GameStargeInit(HWND hWnd)
{
    int i;

    /* ゲーム背景用サーフェイスの生成 */
    CreateGameBackImgSurface(StargeNumber);	// ステージ番号によって、ロードする背景を変える
	
    /* 各ステージ毎に初期化する */
    MyCharaStatusStargeInit(&MyChara, 300, 400, 2, 2); // 自キャラ
    for (i=0 ; i<ENEMY_MAX ; i++) // 敵キャラ
    {
        Enemy[i].life = DEAD;
    }
    EnemyTime = nowTickCount; // 敵キャラ出現時間制御

    /* ステージ別に初期化する */
    switch (StargeNumber)
    {
        case 1: // 1面での初期化
            break;
        case 2: // 2面での初期化
            break;
        case 3: // 3面での初期化
            break;
    }

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

}

4. 敵キャラ発生処理

敵キャラを一定時間ごとに発生させる処理を追加する。

//-----------------------------------------------------------------------------
// 関数名 : GameFrame()
// 機能概要: ゲーム画面更新処理
//-----------------------------------------------------------------------------
void GameFrame(HWND hWnd)
{
    /* ゲーム処理 */
    SetEnemy();	// 出現させる敵キャラをセット
    BackDraw();         // 背景描画処理
    CharDraw();         // キャラクタ描画処理
    CharMove();         // キャラクタ移動処理
    ScreenHitCheck();   // キャラクタがゲーム画面をはみ出しているときの処理
    CharHitCheck();     // キャラクタ同士の当たり判定&処理
    ・
    ・
    ・
}

//-----------------------------------------------------------------------------
// 関数名 : SetEnemy()
// 機能概要: 出現する敵キャラをセットする
//-----------------------------------------------------------------------------
static void SetEnemy(void)
{
    int i, type;

    /* 一定時間ごとに敵キャラを増やす */
    if (nowTickCount - EnemyTime >= ENEMY_INTERVAL)
    {
        EnemyTime = nowTickCount;
        for (i=0 ; i<ENEMY_MAX ; i++)
        {
            if (Enemy[i].life == DEAD) // 使える配列を探す
            {
                type = (int)(5.0 * ((double)rand() / (double)RAND_MAX)); // 出現させる敵の種類はランダム
                EnemyStatusInit(&Enemy[i], type);
                break;
            }
        }
    }

}

※一定時間が過ぎたら空いている配列を調べ、そこに敵キャラ情報を格納する
※敵キャラ情報はタイプによって違うため、EnemyStatusInit関数で設定する(Enemy.cpp内に設置済み)
※1匹しかセットしないため、breakでfor文を抜ける

第14章3確認問題1(必須問題)

14−2で作成したプログラムに上記修正を行い、500ミリ秒ごとに敵キャラが振ってくることを確認しなさい。

実行結果サンプル

第14章3確認問題2(自由問題)

上記プログラムを改造する。現在敵キャラは0から4の5種類いるが、敵5として、自分が考えた動きをする敵キャラを作成しなさい。


[ TOP ]