時間の考え方

この章で使用するプログラムおよび画像ファイル

ゲームでは「何秒以内に○○をおこなう」、「10カウントダウンさせる」、「クリアタイムを計る」など、時間を使った処理は結構多い。
ここでは、プログラム上でどのように時間を取得し、利用するかを学ぶ。

timeGetTime関数

Windowsには、マシンを起動してからどれだけ時間がたっているかを調べるAPI関数として「TimeGetTime関数」「GetTickCount関数」がある。
この関数はシステムが起動してからの時間をミリ秒単位で返す。windows.hでは次のようにプロトタイプ宣言されている。

DWORD timeGetTime(void);

この関数を実行した戻り値を使うことによって、様々な時間制御を行うことができる。

ゲームの開始時間・終了時間を求める

ではこの関数を使って、ゲームの開始時間と終了時間を求めるプログラムを作成してみる。Windowsプログラムの場合、ゲームの開始時間、終了時間は次のように考えることができる。

よって、WinMain関数に入ったときと出る直前でそれぞれtimeGetTime関数を実行し、結果を表示すればよいことが分かる。WinMain関数を修正し、ゲーム開始時間と終了時間をデバッグ・ウィンドウに表示してみよう。

//-------------------------------------------------------------------------------------------------
//      メイン関数(エントリーポイント)プログラムはここから始まる
//-------------------------------------------------------------------------------------------------
int WINAPI WinMain(HINSTANCE hThisInst, HINSTANCE hPrevInst, LPSTR lpszArgs, int nWinMode)
{
    MSG msg;		// メッセージ構造体変数
    HRESULT hr;
    char  buff[80];
    DWORD gettime;  // 取得した時間を格納

    // ゲーム開始時間を取得し、表示
    gettime = timeGetTime();
    wsprintf(buff, "ゲーム開始時間:%d ミリ秒\n", gettime);
    OutputDebugString(buff);

    //表示するウィンドウの定義、登録、表示
    if ( !InitApp(hThisInst, nWinMode) )	// InitApp関数を呼び出し、
        return (FALSE);						// 正常に終了すれば次にメッセージループへ

    // DirectX8の初期化
    hr = InitDX8();
    if ( FAILED(hr) ) return (FALSE);

	// 描画の設定
	InitRender();

    // ゲームループ
    while ( TRUE ) {
    // メッセージがあるかどうか
        if ( PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE) ) {
            // メッセージを取得し、WM_QUITかどうか
            if ( !GetMessage(&msg, NULL, 0, 0) ) break;
            TranslateMessage(&msg);  //キーボード利用を可能にする
            DispatchMessage(&msg);  //制御をWindowsに戻す
        } else if ( g_appActive ) {
            // ゲームメイン処理
            if ( FAILED( UpdateFrame() ) ) break;
            Sleep(1);
        } else {
            WaitMessage();
        }
    }

    // DirectX8オブジェクトの削除
    ReleaseD3D();

    // ゲーム終了時間を取得し、表示
    gettime = timeGetTime();
    wsprintf(buff, "ゲーム終了時間:%d ミリ秒\n", gettime);
    OutputDebugString(buff);

    return msg.wParam;
}

上記のようにプログラムを修正してビルドを行い、デバッグ・モードで実行後、適当なところでプログラムを終了する。すると、デバッグ・ウィンドウに次のような実行結果が表示される。

・
・
・
ゲーム開始時間:26242124 ミリ秒
・
・
・
ゲーム終了時間:26245639 ミリ秒
スレッド 0x474 終了、終了コード 0 (0x0)。
プログラム 'E:\game\Debug\game.exe' はコード 0 (0x0) で終了しました。

上記結果の場合、マシンを起動してから 26242124ミリ秒後 にゲームが開始され、26245639ミリ秒後にゲームが終了したことが分かる。

ゲームを開始(実行)してから終了するまでの経過時間を求める

先ほどのプログラムの実行結果として表れる数値は、実行するたびに変わる。しかし、開始と終了の2つの値の差を求めることにより、ゲームが開始してから終わるまでどれだけの時間が経過したかが分かる。

経過時間 = ゲーム終了時間 − ゲーム開始時間・・・ミリ秒

上記結果の場合、経過時間は 26245639 - 26242124 で 3515ミリ秒であることが分かる。1秒は1000ミリ秒なので、秒に換算すると、約3.5秒である。

このように、任意の2箇所の時間を調べ、その差を求めれば経過時間が分かる。この技術を利用し、様々な時間制御を行うことができる。次項以降では、よく使うと思われる時間制御を使ったプログラムを紹介していく。



NEXT(FPSを調べる)