views:

457

answers:

7

I have a course exercise in OpenGL to write a game with simple animation of a few objects

While discussing with my partner our design options we've realized we have two major choices for how the animation is going to work, Either

  • Set a timer for a constant interval, say 30 msec, when the timer hits, calculate where objects should be and draw the frame. or -
  • Don't use a timer, just a normal loop that runs all the time and in each iteration check how much time passed, calculate where the objects should be according to the interval and draw the frame.

What should generally be the preferred approach? Does anyone have concrete experience with either approach?

+1  A: 

The second would be my preferred approach, because timers are often not as accurate as you're probably thinking and have all the latency and overhead of the event handling system. Accounting for the time interval will give your animations a much more consistent look and be robust if/when your frame rate dips.

Having said that, if your animation is based on a physics simulation (eg rigid body or ragdoll animation), then having a fixed update interval for your physics can greatly simplify the implementation.

MandyK
+6  A: 

Render and compute as fast as you can to get the maximum frame rate (as capped by the vertical sync)

Don't use a timer, they're not reliable < 50-100 ms on Windows. Check how much time has passed. (Usually, you need both delta t and an absolute value, depending on if your animation is physics or keyframe based.)

Also, if you want to be stable, use an upper/lower bound on your time-step, to go into slow-motion if a frame takes a few secs to render (disc access by another process?) or skip an update if you get two of them within say 10 ms.

Marcus Lindblom
+1 Good point about stability.
gnovice
+1 for upper/lower bounds
epochwolf
A: 

Use the second method. Did a game for my senior project and from experience, there is no guarantee that your logic will be done processing when the timer wants to fire.

Kevin Sheffield
A: 

Option 2 is by far preferred. It will scale nicely across differently performing hardware.

The book "Game Programming Gems 1" had a chapter that covers exactly what you need:

Frame Rate Independent Linear Interpolation

dicroce
A: 

I would be tempted to use the loop, since it will render as fast as possible (i.e. immediately after your physics computations are done). This will probably be more robust if you run into any slow-down in computation, which would cause timer firings to start queueing up. However, in case of such a slow-down you may have to put a cap on the time step computed between updates, since your physics engine may go unstable with too large a jump in time.

gnovice
A: 

I'd suggest setting the system up to work on a "delta" that's passed in from outside.

When I did this, inside the animation format I based everything on real time values. The delta I passed in was 1 / 30 seconds, but it could be anything. With this system you can get either your first or second option, depending on whether you pass in a fixed delta or if you pass in the amount of time that has passed since the last frame.

As for which is better, it depends on your game and your requirements. Ideally all of your systems would be based around the same delta so that your physics match your animations. If your game drops frames at all and if all of your systems work with a variable delta, I'd suggest the variable delta is the better of the two solutions for end user experience.

Dan Olson
+2  A: 

Read this page about game loops.

In short, set a timer:

  • Update the state of the game at a fixed frequency (something like every 25 ms = 1s/40fps). That includes the properties of the game objects, the input, the physics, the AI, etc. I call that the Model and the Controller. The need for a fixed update rate comes from the problems that may appear on too slow or too fast hardware (read the article). Some physics engine also prefer to update at a fixed frequency.

  • Update the frame (the graphics) of the game as fast as possible. That would be the View. That way you'll provide a smooth game. You can also enable vsync so the display will wait for the graphic card (usually it's 60 fps).

So each iteration of the loop, you check if you should update the model/controller. If it's late, update until they are up to date. Then, update the frame once and continue your loop.

The tricky part is that because of the different update rates, in fast hardware, the view will update several times before the model and controller. Therefore you should interpolate the position of your game objects depending on "where they would be if the game state would have been updated". It's really not that difficult.

You may have to maintain 2 different data structures : one for the model and one for the view. For instance you could have a scene graph for your model and a BSP tree for your view.

Splo
Scene graphs are evil, but +1 for fixed update for physics.
BigSandwich