Jump to content
  • Advertisement
Sign in to follow this  
MadMax1992

Best approach to game timing

This topic is 3679 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I know how to time a game, I understand the two ways of timing games. The problem I have is animation in a timed 2D game. What is the best way of tackling this program (considering all kinds of animations will be playing at the same time, with different frame lengths and a variable number of frames)? Do I want to do animation like this:
PSEUDOCODE (MANAGER NOT IMPLENTED LIKE THIS):

If (TargetFPSIsReached()) {
for (int i = 0; i < numAnimatedSprites; i++) {
sprites.ticks++;

if (sprites.ticks * targetFPS > sprites.frametime) {
sprites.nextframe();
}
}
I'm a little bit lost here, could you guys help me out? Thanks in advance, Max Henger

Share this post


Link to post
Share on other sites
Advertisement
I'm not sure if there's a best way of doing timing, as it would depend on the situation. However I currently do all my timing based on small fixed time intervals, a bit like this:

Pseudocode:

// Get time delta, the amount of time that has passed since the last update
new_time = SystemGetTime();
time_delta = new_time - old_time;
old_time = new_time;

// for each time interval that's passed, perform an update
while (time_delta >= TIME_TICK_INTERVAL)
{
time_delta -= TIME_TICK_INTERVAL;

// do timed stuff in here...
}

This way, if there's a small slowdown it won't effect the operation as the time interval loop will catch up with any lost time. And as the time interval is a fixed amount you won't get caught up in problems with physics if your game needs it, which can be a problem if you use the time_delta directly.

One extention I've left out is that you may need to put some extra conditions on the loop to catch when time_delta is huge for some reason, otherwise your game will hang for a while as the timed loop runs many times. This can be fixed by forcing a maximum number of times the loop can run.

Share this post


Link to post
Share on other sites
Quote:
Original post by Trapper Zoid
One extention I've left out is that you may need to put some extra conditions on the loop to catch when time_delta is huge for some reason, otherwise your game will hang for a while as the timed loop runs many times. This can be fixed by forcing a maximum number of times the loop can run.


I limit game loops, while keeping error constant:


class app;
class game;
class timer;

void app::run()
{
const double frame_step_dt = 1.0 / 60.0; // 60 fps

double elapsed_time = 0.0;
double accumulated_time = 0.0;

bool slow_down = false;
bool is_running = true;
timer t;

t.start();
while ( is_running )
{
elapsed_time = t.delta();
t.reset();

// If the game becomes overloaded (m_game->step() takes longer than m_frame_step_dt),
// prevent error by sacrificing game loops by only doing one update in the time
if ( slow_down )
is_running = m_game->step( frame_step_dt );
else
for ( accumulated_time += elapsed_time; accumulated_time >= frame_step_dt; accumulated_time -= frame_step_dt )
is_running = m_game->step( frame_step_dt );

// Check to see if we need to slow down...
slow_down = t.delta() > frame_step_dt ? true : false;

// Use linear-interpolation:
m_game->draw( accumulated_time / frame_step_dt );
Sleep( 0 );
}
}


Share this post


Link to post
Share on other sites
I understand those two ways of limiting the frame time. I'm using them allready. Let me explain my problem with an example:

One sprite in my game uses an animation. The animation contains 4 frames, and takes 4 seconds. I want to see the next frame after one second.

Another sprite in my game uses another animation. The animation contains 4 frames, and takes 8 seconds, so I want to see a new frame after two seconds.

This means I can't increment the frames on all sprites at the same time. What is the best way to tackle this problem?

Share this post


Link to post
Share on other sites
The best way I can think of (the way I did it) is to create an Ani class.

Here's how I did it:
The class contained a Frame struct that stored the image for the frame and that frame's length.
A vector stored all of the frames in order.
A length variable stored the total length of the ani.
A timer to determine the proper frame based on time
A constructor with a bool to determine whether it should loop
A method to add frames to the ani
A method to restart the ani
A method to return the image to draw

Then in my drawing code I would just call use Ani::GetImage() to get the right frame, and draw it at the appropriate place.

To determine the current frame:
time = timer.time();
the current time in the ani can be found with time %= length (unless it doesn't loop)
now we know the right time, so iterate through the frames to find the right one.

Hope this is enough to get you going.

Share this post


Link to post
Share on other sites
Quote:
Original post by MadMax1992
I understand those two ways of limiting the frame time. I'm using them allready. Let me explain my problem with an example:

One sprite in my game uses an animation. The animation contains 4 frames, and takes 4 seconds. I want to see the next frame after one second.

Another sprite in my game uses another animation. The animation contains 4 frames, and takes 8 seconds, so I want to see a new frame after two seconds.

This means I can't increment the frames on all sprites at the same time. What is the best way to tackle this problem?


The post before me explained this already but I just want to reiterate it. Essentially you have an Animation class that, along with the frames themselves, contains its own unique timer.

When you call a GetCurrentFrame() on that Animation the class can determine how much time has gone by since the last call, figure out how many frames have elapsed, and return the correct frame. This way your animation will be "animating" even when not on the screen but you won't have to call an update function on it every frame.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!