2

私はゲームプログラミングに関する本からDirectXを学んでおり、ゲームループには次の方法を使用しています。

long int start = GetTickCount();
while(true)
    GameRun();

void GameRun()
{
     if(GetTickCount() - start >= 30)
         //do stuff
}

これはstart、時間に関係なく等しくなり(get tick countは、プログラムの開始以降の「ティック」の数を示すと思います)、30ティック後に、すべてのAI、レンダリングなどを実行します。

私の質問は、最初にすべてのAIなどを実行してから、時間が残っている場合は、フレームを変更する必要があるまで待つ方が効率的ではないでしょうか。

では、安定したフレームレートを維持するためのより良い方法は何でしょうか?(できれば、サウンド、画像、入力(d3d9.hなど)にすでに使用しているDirectXヘッダーのみを使用することをお勧めします)

また、関連するメモとして、GetTickCount()は正確に何を実行し、「ティック」の長さはどれくらいですか。

4

2 に答える 2

6

ゲームループについては、この記事をお読みください。それはあなたのオプションを要約し、あなたの選択を明確にします。

GetTickCount()の場合、これはWindowsで時間を取得する最も簡単な方法です(UNIX OS用の方法はわかりません)。QueryPerformanceFrequencyとQueryPerformanceCounterははるかに高い精度を提供しますが、それらを正しく使用する方法を理解するのは難しいかもしれません。

Ogre :: Timerクラスがどのように機能するかを読むことに興味があるかもしれません(Ogreはよく知られているオープンソースのリアルタイム3Dレンダリングライブラリです)。彼らはそれらの関数に関するいくつかの潜在的な問題に対処するためにいくつかのコードを追加し、いくつかのプラットフォーム用のコードがあります。

コードを取得して、アプリで使用できます。Ogreの次期バージョンのライセンスはMITです

そうすれば、ゲームループとゲームコードに集中できます。


時間精度の更新:最後のブーストバージョンを使用できる場合は、クロスプラットフォームであり、WindowsでQueryPerformanceFrequencyとQueryPerformanceCounterを使用する高精度のクロックsteady_clockを提供するboost.chronoがあります。実際、クロノはC++標準ライブラリに追加するための提案です。

于 2009-10-17T23:33:20.863 に答える
2

提供したサンプルコードは、ゲームループを実装するための最悪の方法です。お気づきのように、リフレッシュする時まで待つのは大変な無駄です。

任意の時間ステップ(たとえば、1秒)を選択し、この時間ステップに関連するすべての測定値を表現するだけです。

これは次のようになります。

while ( !done )
{
    float alphaTime = timeConstant / (currentTime - lastLoopTime);
    dispatchEvents();
    gameLogic( alphaTime );
}

void gameLogic( float alphaTime )
{
    movePlayer( playerSpeed * alphaTime );
}

このようにして、フレームレートを待つ時間を無駄にすることなく、AIスクリプトを実行させることができます。移動には時間係数が掛けられるため、すべてが同じ速度で移動します。

于 2009-10-17T23:07:26.297 に答える