문제

I'm learning DirectX from a book about game programming, and it uses the following method for a game loop:

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

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

This makes start equal whatever the time is (I'm guessing get tick count gives the number of 'ticks' since the program started), and then, 30 ticks later, does all of the AI, rendering, etc.

My question is, wouldn't it be more efficient to do all of the AI, etc. first, then, if theres time left over, wait until the frame needs to be changed?

So, what would be a better way to keep a steady frame rate? (Preferably only using DirectX headers that I would already be using for sound, images and imput (like d3d9.h))

And, on a related note, what exactly does GetTickCount() do, and how long is a 'tick'

도움이 되었습니까?

해결책

For your game loop, read this article. It sum-up your options and makes your choice clear.

Now for GetTickCount(), it's the simplest way to get time in Windows (I don't know the one for unix OSes). QueryPerformanceFrequency and QueryPerformanceCounter gives far more precision but might be hard to understand how to use them right.

You might be interested in reading the way the Ogre::Timer class works (Ogre is a well-known open-source real-time 3D rendering library). They added some code to deal with some potential problems with those functions and there is code for several platforms.

You can take the code and use it in your apps, .the license of the coming version of Ogre is MIT

That way you can concentrate on your game loop and the game code.


UPDATE ON TIME PRECISION : now if you can use the last boost version, there is boost.chrono that provide a high precision clock, steady_clock, that is cross platform and uses QueryPerformanceFrequency and QueryPerformanceCounter on windows. In fact, chrono is a proposition for addition to the C++ standard library.

다른 팁

The sample code you provided is the worst way to implement a game loop. As you noticed, it is just a huge waste to wait until it's time to refresh.

Just choose an arbitrary time step (say, one second for instance) and express all your measures relatively to this time step.

This would look like:

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

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

This way you don't waste time waiting for the framerate, you can let your AI scripts runs, ... and everything will move at the same speed, since movements are multiplied by the time factor.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top