Slowing Game Down

Moderator
Posts: 608
Joined: 2002.04
Post: #1
I am making a game on a rather old machine, so I had to optimize it a lot, but now I fear that it may run too quickly on newer machines. What is the best way to set a constant frame rate? Right now I do this:
Code:
float startTime;

while(done == false)
{
startTime = TickCount();
EventLoop();
UpdateWindow();
while(TickCount() < startTime + 1.5)
}
Is this the best way? Does this keep the frame rate at or below 40 FPS?
Quote this message in a reply
CMagicPoker
Unregistered
 
Post: #2
Keeping the simulation speed by capping the fps is not the recommended way.
And there's the problem that 'Tickcount()' is not precise.
You should use something like the Time Manager instead.

I suspect that your game is slower when it runs at a slower framerate.
Quote this message in a reply
Mutle
Unregistered
 
Post: #3
I think you should use UpTime() instead of TickCount().
I don't know if UpTime() is supported in OS 9, but otherwise, you could also use Microseconds().
Quote this message in a reply
kainsin
Unregistered
 
Post: #4
Microseconds() is a good way to keep very precice control, however TickCount() should be just fine for running games that don't require too much processing power. Keep in mind that TickCount() returns a long int not a float so it would be pretty difficult to get 40 frames per second. If you need to keep it at 40 frames per second then you can use Microseconds() for more acurate time management. Otherwise you can try to go for 60 fps or 30 fps and use TickCount().

One thing that is wrong with your event loop is that you are using a while loop to measure time. This method of time management is not very friendly to other applications. Instead try to implement something like:
Code:
long int nextFrameTime = TickCount() + 2; // 30 fps

while( done == false ) {
    OneEventLoopCycle();
    
    if( TickCount() >= nextFrameTime ) {
        nextFrameTime = TickCount() + 2;
        AnimateOneFrame();
    }
}
This way your application can still process events between frames and allow other applications to do some background processing.

Note: If you are going to be moving your application to Carbon then I suggest using the Carbon Event Manager and use timers to control your animation. It's a lot less work than the classic WaitNextEvent/GetNextEvent event loops.
Quote this message in a reply
CMagicPoker
Unregistered
 
Post: #5
There's a Time tutorial I found once, a really good one.
I found it on iDevGames, hehe.

Why my rank said I was a guest, I inputed my correct password, I know some other got this problem, what it is?
Quote this message in a reply
swcrissman
Unregistered
 
Post: #6
Regarding the code that kainsin posted, typically, its what you want to to do, but if you are worried that your game is going to run too quickly, then you will need to either put the OneEventLoopCycle() inside your time checker, or make sure that your physics engine and such know how long its been since the last tick. Otherwise, you'll only draw at 30 fps, but will update too many times, causing the game to still play fast. Since usually people are worried about the game not playing fast enough, its kind of the reverse of what you'd normally do, but that seems to be your concern, so...

Spencer
Quote this message in a reply
kainsin
Unregistered
 
Post: #7
Yeah, I usually regard the Event Loop Cycle as the check for system events ( mouse clicks, key presses, etc. ) and the Animation Cycle as the check for all the calculations that need to be done in order to draw one frame ( finding out how far the sprites move, changing sprite pictures, collision, etc. ). It's just a simplified version.
Quote this message in a reply
Taliesin
Unregistered
 
Post: #8
Whatever you end up doing, whether you use MicroSeconds, UpTime, or stick with Ticks, DO NOT DO THIS:

while(TickCount() < startTime + 1.5)

Spin loops are bad juju - play nice with the rest of the system, and the rest of the system will play nice with you.

Use carbon timers that fire as often as possible, say every millisecond or so. From the carbon timer callback, calculate a delta time that will give you a fairly constant framerate. Even better, don't tie your animation to your framerate. Update all your objects frequently on the delta time, and draw as often as you can. Faster machines will give more FPS, slower ones may be slightly jerky, but work with what you are capable of doing.

If you need to have a constant framerate, consider something of the form

if(deltaTime > kFrameRate) {
....
}

rather than

while(deltaTime <= kFrameRate){};

Your users will thank you, and you won't use nearly as much CPU time.
Quote this message in a reply
Post Reply