今度は、スタート画面から一定時間経過したらデモムービーを流すプログラムを考える。デモムービーは再生時間が長いことが多いため、再生中に任意のキー(ボタン)を押したら再生を中止し、スタート画面に戻れるようにプログラムする必要がある。
スタート場面やゲーム場面などと同じ扱いで、デモ場面を作成する。
デモ場面を状態別処理として扱うため、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
デモムービーの再生は、デモ画面処理の最初で一度行えばよく、その後、ムービーが終了したり任意のキー(ボタン)を押したらスタート画面に戻るようなプログラムにすればよい。
よって、ムービーの再生は「初期化処理(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);
}
スタート画面表示時、何もしないで一定時間経過したらデモムービーが流れるよう、Start.cppを次のように修正する。
//============================================================================= // スタート処理関係の自作関数群 // 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; // スタート画面で何もしていない時間
//-----------------------------------------------------------------------------
// 関数名 : 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;
}
//-----------------------------------------------------------------------------
// 関数名 : 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++;
}
}
}
※以上の修正を行ったらビルドを実行し、スタート画面表示後、一定時間が経過したらデモムービーが表示され、ムービーが終了/再生中にスペースキーを押したら、スタート画面に戻ることを確認する。
| BACK(ロゴムービーが流れてからスタート画面を表示させるには?) |