一定時間経過したらデモムービーを流すには?

今度は、スタート画面から一定時間経過したらデモムービーを流すプログラムを考える。デモムービーは再生時間が長いことが多いため、再生中に任意のキー(ボタン)を押したら再生を中止し、スタート画面に戻れるようにプログラムする必要がある。

デモムービーのサンプルファイル(demo.mpg)

デモ場面の追加

スタート場面やゲーム場面などと同じ扱いで、デモ場面を作成する。

1.デモ場面用の状態別の値を作成

デモ場面を状態別処理として扱うため、NKC_Common.hに状態を判別する値を次のように追加する。

/* ゲームの状態を識別する(フレーム番号) */
#define LOGO_FRAME      0
#define START_INIT      10
#define START_FRAME     11
#define DEMO_INIT       20
#define DEMO_FRAME      21
#define GAME_INIT       30
#define GAME_STAGEINIT  31
#define GAME_FRAME      32
#define GAMEOVER_INIT   80
#define GAMEOVER_FRAME  81
#define GAMECLEAR_INIT  90
#define GAMECLEAR_FRAME 91

《注意》

2.デモムービー再生処理/デモムービー終了・中断処理の追加

デモムービーの再生は、デモ画面処理の最初で一度行えばよく、その後、ムービーが終了したり任意のキー(ボタン)を押したらスタート画面に戻るようなプログラムにすればよい。
よって、ムービーの再生は「初期化処理(DEMO_INIT)」で行いムービーの終了や中断の判定処理は「デモ再生処理(DEMO_FRAME)」で行うよう、状態別処理(WinMain.cpp内のUpdateFrame()関数)を次のように修正する。

//-----------------------------------------------------------------------------
// 関数名 : UpdateFrame()
// 機能概要: ゲームメイン処理
//-----------------------------------------------------------------------------
BOOL UpdateFrame(void)
{
    /* 現在の時間を取得 */
    gl_nowTime = timeGetTime();

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

    /* 画面のクリア */
    gl_lpD3ddev->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0,0,0), 0.0, 0);
    /* シーン開始 */
    gl_lpD3ddev->BeginScene();
    /* 頂点フォーマットを設定 */
    gl_lpD3ddev->SetVertexShader(FVF_TLVERTEX);

    /* 処理の振り分け */
    switch ( g_FrameNo ) {
        case LOGO_FRAME:
            // ロゴムービーの再生処理を実行
            MoviePlayNonStop("logo.mpg");
        case START_INIT:
            // スタート画面を表示する前に実行する初期化関数を実行
            StartInit();
        case START_FRAME:
            // スタート画面表示処理関数を実行
            StartFrame();
            break;
        case DEMO_INIT:
            // デモムービーの再生を実行
            if ( FAILED(InitDShow("demo.mpg")) ) return FALSE; // DirectShowの初期化
            g_FrameNo = DEMO_FRAME;
        case DEMO_FRAME:
            // デモムービーの終了・中断処理
            if ( gl_KeyTbl[VK_SPACE] & 0x80 )
                ReleaseDShow();
            else
                MoviePlayCheck();
            if ( g_movieFlg == FALSE ) g_FrameNo = START_INIT;
            break;
        case GAME_INIT:
            // ゲーム画面を表示する前に実行する初期化関数を実行
            GameInit();
        case GAME_FRAME:
            // ゲーム画面表示処理関数を実行
            GameFrame();
            break;
        default:
            MessageBox(hWnd, "g_FrameNoの値が例外です。", "ERROR", MB_OK);
            return (FALSE);
    }

    /* シーン終了 */
    gl_lpD3ddev->EndScene();
    /* フリップ(ムービー再生中はフリップを行わない) */
    if ( g_movieFlg == FALSE ) gl_lpD3ddev->Present(NULL, NULL, NULL, NULL);

    return (TRUE);
}

《POINT》

スタート処理の修正

スタート画面表示時、何もしないで一定時間経過したらデモムービーが流れるよう、Start.cppを次のように修正する。

1.スタート処理用グローバル変数の宣言

//=============================================================================
//  スタート処理関係の自作関数群
//  Copyright NKC Game Staff(←自分の名前) 
//-----------------------------------------------------------------------------
#include "NKC_Common.h"

// マクロの定義
#define MENU_COUNT 4
#define CURSOR_MOVETIME 500
#define DEMO_STARTTIME 60000 // デモムービーを開始する時間

// グローバル変数
/* 自ソースでのみ利用するもの */
static TLVERTX BackVertex[4];               // 背景用頂点情報配列
static TLVERTX MenuVertex[4];               // メニュー用頂点情報配列
static TLVERTX CursorVertex[MENU_COUNT][4]; // カーソル用頂点情報配列
static int gl_MenuNo;                       // 選択されているメニュー番号
static DWORD gl_CurMoveTime;                // カーソル移動後経過時間
static DWORD gl_WaitTime;                   // スタート画面で何もしていない時間

2.スタート画面初期化処理

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

    // スタート画面で使用するテクスチャの作成
    CreateStartTexture();

    //--------------------------------------------------- 各変数の初期化
    /* 背景 */
    InitVertex(BackVertex, (float)gl_rcScreen.left, (float)gl_rcScreen.top, (float)gl_rcScreen.right, (float)gl_rcScreen.bottom, 255);
    /* メニュー */
    MenuInitVertex(MenuVertex, 200.0f, 250.0f, 400.0f, 442.0f);
    /* カーソル */
    MenuInitVertex(CursorVertex[0], 150.0f, 250.0f, 200.0f, 300.0f);
    MenuInitVertex(CursorVertex[1], 150.0f, 298.0f, 200.0f, 348.0f);
    MenuInitVertex(CursorVertex[2], 150.0f, 346.0f, 200.0f, 396.0f);
    MenuInitVertex(CursorVertex[3], 150.0f, 394.0f, 200.0f, 444.0f);
    /* カーソル表示位置(選択されたメニュー番号) */
    gl_MenuNo = 0;
    /* カーソルの移動後経過時間 */
    gl_CurMoveTime = 0;
    /* スタート画面での待機時間 */
    gl_WaitTime = gl_nowTime;

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

}

3.スタート画面処理

//-----------------------------------------------------------------------------
// 関数名 : StartFrame()
// 機能概要: スタート画面処理
//-----------------------------------------------------------------------------
void StartFrame(void)
{

    /* 描画処理 */
    // 背景
    gl_lpD3ddev->SetTexture(0, gl_TXBack);
    gl_lpD3ddev->DrawPrimitiveUP(D3DPT_TRIANGLEFAN, 2, BackVertex, sizeof(TLVERTX));
    // メニュー
    gl_lpD3ddev->SetTexture(0, gl_TXMenu);
    gl_lpD3ddev->DrawPrimitiveUP(D3DPT_TRIANGLEFAN, 2, MenuVertex, sizeof(TLVERTX));
    // カーソル
    gl_lpD3ddev->SetTexture(0, gl_TXCursor);
    gl_lpD3ddev->DrawPrimitiveUP(D3DPT_TRIANGLEFAN, 2, CursorVertex[gl_MenuNo], sizeof(TLVERTX));

    // 一定時間待機したら、デモムービーを再生する
    if ( gl_nowTime - gl_WaitTime >= DEMO_STARTTIME ) {
        ReleaseStartTexture();
        g_FrameNo = DEMO_INIT;
        return;
    }
	
    // 選択されたメニューによって、処理を振り分ける
    if ( gl_KeyTbl[VK_RETURN] & 0x80 ) {
        switch ( gl_MenuNo ) {
        case 0:
            ReleaseStartTexture();
            g_FrameNo = GAME_INIT;
            return;
//      case 1:
//          g_FrameNo = GAME_CONTINUE;
//          return;
//      case 2:
//          g_FrameNo = GAME_OPTION;
//          return;
        case 3:
            PostMessage(hWnd, WM_CLOSE, 0, 0); //WM_DESTROYを誘発させる
            return;
        default:
            OutputDebugString("StartFrame関数:g_FrameNoの値が不正です。\n");
        }
    }

    // カーソルの移動
    if ( !( gl_KeyTbl[VK_UP] & 0x80 || gl_KeyTbl[VK_DOWN] & 0x80) ) {
        gl_CurMoveTime = 0;
    } else {
        gl_WaitTime = gl_nowTime;
        if ( gl_nowTime - gl_CurMoveTime > CURSOR_MOVETIME ) {
            gl_CurMoveTime = gl_nowTime;
            if ( gl_KeyTbl[VK_UP] & 0x80 && gl_MenuNo > 0 ) gl_MenuNo--;
            else if ( gl_KeyTbl[VK_DOWN] & 0x80 && gl_MenuNo < MENU_COUNT - 1 ) gl_MenuNo++;
        }
    }

}

《POINT》

※以上の修正を行ったらビルドを実行し、スタート画面表示後、一定時間が経過したらデモムービーが表示され、ムービーが終了/再生中にスペースキーを押したら、スタート画面に戻ることを確認する。


BACK(ロゴムービーが流れてからスタート画面を表示させるには?)