Set Constant Throttle in Milliseconds
Main Game Loop
Get Start Time
Select Case GameState
Demo
Intermission
Playing
Paused
GameOver
Get Finish Time
if ((Finish - Start) < Throttle) then
pause for (Throttle - (Finish-Start)) milliseconds
Loop
Right now my Throttle is set to 10ms... it that too small? Originally I had it set to 250ms, but I thought that was too high. Is there a way to determine the best throttle value for a game? Any advice and or new timing algorithms would be appreciated, thanks.
P.S. Slightly off topic but... is there an advantage to creating seperate internal loops for each of the the various game states? Currently I just call the appropriate procedure which ultimately returns to the main game loop to re-check the game state and perform timing each cycle. It seems like a lot more work to create seperate loops for each state, but someone mentioned it to me once and I just wondering if there were any benefits in doing so.
Game Timing...
Just curious, what is the best method of game timing, and what is a decent throttle value. Currently I use the following:
Pseudo Code:
why restrict it at all? just use frame-based modeling where you move your objects like this:
object_x=speed_x*throttle
object_y=speed_y8throttle
throttle is more commonly called delta, but it doesn''t really matter.
HHSDrum@yahoo.com
Polarisoft Home Page
object_x=speed_x*throttle
object_y=speed_y8throttle
throttle is more commonly called delta, but it doesn''t really matter.
HHSDrum@yahoo.com
Polarisoft Home Page
Urgh. It bugs me when people do that to time their games.
I recommend either:
1. Keep track of your loop time, and multiply all your physics movement by the last loop time (that way people with faster machines will get better frame rates).
2. Keep track of loop time, and run your logic every X hz, render every Y Hz, take input every Z Hz, etc ... so, let''s say you want the following rates:
Logic = 20Hz = 50 millisecondsInput = 10Hz = 100 millisecondsPhysics = 100Hz = 10 millisecondsRender = as fast as possible
So, get the last loop time and add it to each of separate logic, input, and physics timers. If enough time has ticked by to run logic, run the logic, and subtract 50 from the logic counter. If enough time has ticked by to poll input, poll input and subtract 100 from the input timer. If enough time has ticked by to do the physics, do a physics run, and subtract 10 from the physics timer. Note, if your last loop time was, say, 25 milliseconds, you will run physics twice. Then, once per loop, (if anything has moved) do a render. Alternately, you can render every frame, and interpolate positions, but this is more difficult.
Both methods have their pros and cons. I have used both.
Throttling (your method) works, but has the disadvantage that faster computers will get the same frame rate as slower computers, and if the computer is slow enough to run slower than your throttle value, everything will look slow-motion.
Here''s my method:
It works good for me, although it may not be the most effective counter int the world....
Hope that helps
//------------------------------------------------------------------------// Name: WaitTime()// Desc: Waits for time to pass//------------------------------------------------------------------------bool WaitTime(int time){ static int CurrentTime = 0; static int LastTime = 0; int TimeDelta = 0;#ifdef WIN32 if (LastTime == 0) // first init LastTime = GetTickCount(); CurrentTime = GetTickCount(); TimeDelta = CurrentTime - LastTime; if (TimeDelta >= time) { LastTime = CurrentTime; return true; }#endif return false;// use it like this...void GameMain(){ if (!WaitTime(150)) return; // do game stuff here....}
It works good for me, although it may not be the most effective counter int the world....
Hope that helps
Anonymous Poster, do you know of any good tutorials and or examples of the method you described. I''d like to look into it further. For my current project (a simple pacman clone) I just needed a constant frame rate, which is why I choose the easy way out. But I plan to work on some bigger projects and would like to know not only how to implement a better timer, but the pros and cons behind using it.
Xorcist, here''s is the frame-delta code I use. Its the best way to time your game, though the only problem is if the game runs at >200FPS, DInput may stumble so just make sure you limit the FPS to 60-75FPS via your DirectGraphics init routine.
Note; The Blit() function would be your own routine.
Hope this helps
// Global variablesfloat g_fCalcDelta;__int64 PerfTimerRate;__int64 PerfTimerDivider = 0;// Call this on game initbool InitPerfTimer(void){ __int64 tempInt64; // Aquire the timer frequency if(!QueryPerformanceFrequency((LARGE_INTEGER*)&PerfTimerRate)) { return FALSE; // System doesnt have a Performance timer } // Check the rate (usually 1193180) if(PerfTimerRate==0) { return FALSE; } // Calculate millisecond divider PerfTimerDivider = (__int64)( (__int64)PerfTimerRate / 1000); if(!QueryPerformanceCounter((LARGE_INTEGER*)&tempInt64)) { return FALSE; // win errors } return TRUE; // Success}WORD FTime(void){ __int64 tempInt64; QueryPerformanceCounter((LARGE_INTEGER*)&tempInt64); return (WORD)((_int64)tempInt64 / (__int64)PerfTimerDivider);}// Call this every frame to get the frame diff.void UpdateTimeDeltas(){ static WORD timerDelta = 0; static WORD oldftime = 0; static WORD newftime = 0; static WORD oldnDiff = (WORD)FTime(); // Calculate the frame delta. newftime = FTime(); if( oldftime > newftime ) oldftime = newftime; timerDelta = newftime - oldftime; oldftime = newftime; float fCalcDelta = float(timerDelta / 1000.0f); // Set the global fCalcDelta and counter. g_fCalcDelta = fCalcDelta;}// Call every frame to update the sprite positions.void UpdateSprites(bool bLeft, bool bRight){ // Player velocity vel = 100.0f; if(bLeft) Player.xpos -= g_fCalcDelta * vel; if(bRight) Player.xpos += g_fCalcDelta * vel; // Note ''Player.xpos'' is a float variable.} As for the background scrolling, give your background and main sprite a global position, and whenever you update the position of the main sprite, at the same time update the position of the background minus the sprite offset of the main sprite.For example (640x480): void SetBgndPos(){ // Center the player. Level.xpos = WORD(Player.xpos) - 320; Level.ypos = WORD(Player.ypos) - 240;}void UpdateFrame(){ // Set the Bgnd pos in relation to the player pos. UpdateTimeDeltas(); UpdateSprites(..DInput status..); SetBgndPos(); // Blit the background tiles. Blit(Level.lpDDSurface, Level.xpos-640, Level.ypos); Blit(Level.lpDDSurface, Level.xpos, Level.ypos); Blit(Level.lpDDSurface, Level.xpos+640, Level.ypos); // Blit the sprite Blit(Player.lpDDSurface, 320, Player.ypos); }
Note; The Blit() function would be your own routine.
Hope this helps
Downloads: ZeroOne Realm
SikCiv,
Personally I prefer rendering at a specific framerate, as it simplifies many things. But if you want to run as fast a possible why don''t you thread the input routines so that whenever you get data from directinput you change some state variables, that why you are running your main loop full tilt without the bother of waiting around for windows to keep up.
Xorcist,
Fixed or as fast as possible both have advantages, but one thing to think about is will your game have reproducable behavior? can you replay a sequence of events and get the same results? Take a look at one of the recent features from gamasutra.com on the subject.
Cheers
Personally I prefer rendering at a specific framerate, as it simplifies many things. But if you want to run as fast a possible why don''t you thread the input routines so that whenever you get data from directinput you change some state variables, that why you are running your main loop full tilt without the bother of waiting around for windows to keep up.
Xorcist,
Fixed or as fast as possible both have advantages, but one thing to think about is will your game have reproducable behavior? can you replay a sequence of events and get the same results? Take a look at one of the recent features from gamasutra.com on the subject.
Cheers
Snowmoon,
If you rely on the framerate, what happens when the framerate is slower than 60-75FPS? The gameplay and sprite movement will slow down and may render the game un-playable on slower systems. With the frame-delta method you can garantee smooth gameplay no matter what the framerate is, though I guess it depends on how complicated the game is. In my case I need it to be precise since it my game consists of hundreds of sprites with varied velocities, the higher the framerate is, the smoother everything moves.
As for the DInput stall, it wasnt specifically a DInput problem, more to do with the video card reference drivers I was using - the GeForce256 can run at 400+ FPS with the refresh wait disabled resulting in a delay in other game functions - most noticably the user-input. I fixed the problem by installing the proper Asus drivers and everything is fine now
If you rely on the framerate, what happens when the framerate is slower than 60-75FPS? The gameplay and sprite movement will slow down and may render the game un-playable on slower systems. With the frame-delta method you can garantee smooth gameplay no matter what the framerate is, though I guess it depends on how complicated the game is. In my case I need it to be precise since it my game consists of hundreds of sprites with varied velocities, the higher the framerate is, the smoother everything moves.
As for the DInput stall, it wasnt specifically a DInput problem, more to do with the video card reference drivers I was using - the GeForce256 can run at 400+ FPS with the refresh wait disabled resulting in a delay in other game functions - most noticably the user-input. I fixed the problem by installing the proper Asus drivers and everything is fine now
Downloads: ZeroOne Realm
SikCiv,
Generally I don''t shoot for 60.. I''m shooting for 30fps so the
bar is quite low to begin with. If the game notices a slowdown
where it is missing a signifigant number of redraws it starts
skipping drawing some frames. I''m also reliant on character
animations that are based on a specific framerate.
I like the idea up top where each logic function takes a set
ammount of time, but I''m not sure how you would resolve the
spacial anomolies from doing the physics calcsand due to fp
rounding the object is not quite where is it supposted to be.
Cheers
Generally I don''t shoot for 60.. I''m shooting for 30fps so the
bar is quite low to begin with. If the game notices a slowdown
where it is missing a signifigant number of redraws it starts
skipping drawing some frames. I''m also reliant on character
animations that are based on a specific framerate.
I like the idea up top where each logic function takes a set
ammount of time, but I''m not sure how you would resolve the
spacial anomolies from doing the physics calcsand due to fp
rounding the object is not quite where is it supposted to be.
Cheers
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement