[Solved] keeping the game at same speed

Started by
9 comments, last by Vyper_uk 18 years, 7 months ago
How can I keep my game to the same speed at diferent frame rates? Before this, I always used the vertical retrace for keep the game at 60 fps, but now I'm starting with Opengl, and I found that in some PCs, Opengl (or something) doesn't perform a vertical retrace, so I get like 170 fps and my game runs very fast. [Edited by - martin_bfg10k on August 22, 2005 7:29:37 PM]
Advertisement
Google for Frame-rate Independent Movement.

Here are some sources to help you get started:

http://www.gamedev.net/reference/articles/article1604.asp
http://www.gamedev.net/reference/articles/article820.asp
:stylin: "Make games, not war.""...if you're doing this to learn then just study a modern C++ compiler's implementation." -snk_kid
by measuring how much time has passed between two frames and using that number in your code

so instead of "x = x + 10" you'd go" x = x + 10 * time_passed"
"It's better to regret something you've done than to regret something you haven't done."
I think I'm right in saying the best thing to do is to make your code frame-rate independant and then you don't have to worry about what the game is running at.

You do this by calculating the time that has passed in each loop and then when you move an object or somthing you factor in the time passed when calculating how far it should have moved. Eg

    ball1->pos.x += (ball1->vel.x * time_passed * DELTA);    ball1->pos.y += (ball1->vel.y * time_passed * DELTA);
It is called "time based movement".

I'm not sure on what system you're programming, but on Windows there is a function called QueryPerformanceCounter(), which has a resolution of 1 ms.

I wrapped everything into a called, but without doing that, let me show you how it would work:
long frequency = 0;long startTick = 0;long endTick = 0;float timeDelta = 0.0f;// Get the frequency of the timerif (!QueryPerformanceFrequency(&frequency))     Error("CAn't use PerformanceCounter");QueryPerformanceCounter(&startTick);Update(timeDelta);Render();QueryPerformanceCounter(&endTick);timeDelta = (endTick - startTick) / (float)frequency;


That piece of code gets you the time it took to render the current scene. You Update() would look like this:
void Update(float timeDelta){    // player.movement contains the speed of the player PER SECOND. If you determine, that the player would move 50 pixels per second, and the last frame took 100ms to render, the player will move 5 pixels.    player.x += player.movement * timeDelta;    player.y += player.movement * timeDelta;}


You basicly just multiply all the movement values by the elapsed time.

Toolmaker

Quote:I'm not sure on what system you're programming, but on Windows there is a function called QueryPerformanceCounter(), which has a resolution of 1 ms.


Accutually, alot better than one ms..



Anyway.. Everyone seems to suggest deltatime based movement.. But there's another way as well, where you wont have to modify your game as much..

Here's an explanation of it:
http://www.iki.fi/sol/gp/ch09.html
That example uses SDL, but just follow the principles.. It's pretty easy when you think of it..

Those articles are very usefull, specialy thee last one, now I think I have something where to start. Thanks for the help. :)
Hey, I am wondering, you said something like multiply by time passed, but what about like having a game timer similar to an FPS lock which is a for loop, and then you just loop it x times depending on how much time has passed and in the loop it just does everything as it normally would?
@ScottC

Busy loops are considered bad programming practice because on some operating systems the "idle" time of the processor is used by device drivers to execute their magic. Furthermore it performance varies depending on the cache sizes of different processors. Lastly busy loops heat up the processor. You're better off using a timer.
Quote:Original post by samuraicrow
@ScottC

Busy loops are considered bad programming practice because on some operating systems the "idle" time of the processor is used by device drivers to execute their magic. Furthermore it performance varies depending on the cache sizes of different processors. Lastly busy loops heat up the processor. You're better off using a timer.


I don't know if you clearly understood what I was talking about...

So say we want to advance the game every .05 seconds. Rendering takes so long that we don't get to the actual game loop for .20 seconds, so because of that we run the game loop four times before going on to render once again. Bad idea?

This topic is closed to new replies.

Advertisement