There is a main game loop in my program, which calls game update every frame. However, to make better animation and better control, there is a need to implement a function like updateEveryNFrames(n, func).

I am considering implementing a counter for each update. The counter will be added by one each frame. The update function will be invoked according to the counter % n.

For example, in a sequence of sprites animation, I can use the above function to control the speed of the animation.

Can some give some advice or other solutions?


1 Answer 1


So what you want is one loop to run slow (say 10 fps or hz), and another loop for animation to run faster (30fps or hz), yes?

You can do it the way you say but actually it's much simpler when done something like:

//we are working in ms for setTimeout's sake; 1000ms per second
var LOGIC_FREQ = 10;

setTimeout(ANIMATION_PERIOD, updateAnimation);
setTimeout(ANIMATION_PERIOD, updateGameLogic);

void updateAnimation() { ... do animation stuff... }
void updateGameLogic() { ... do game logic stuff... }

There is nothing wrong with just running two separate timers in parallel like this -- since your view should be well decoupled from your data and control logic anyway.

An excellent source on how best to implement timing is Gaffer's Fix Your Timestep.

As to what you do inside updateGameLogic:

  1. Accept input from player(s) (via input devices, eg. pressing up arrow might equate to input code "up")
  2. Accept input from AIs (via either functions or classes that produce same as input codes for player, eg. FSM AI wants to go up means it will produce output "up")
  3. Based on inputs, perform your basic physics or otherwise do movement per entity, and add new entities. You must not add or remove entities directly to your entity list in this phase, because you are still in the midst of processing the entity list. You can add eg. new bullet entities in this phase by adding them to an "additions" list.
  4. Run through entities, testing each against every other for a possible collision (see 2nd part of my answer here). Any entities that get expired (eg. due to a collision) must still not be removed immediately, but rather added to a "removals" list (because otherwise you will break the list while it's being processed for physics.
  5. Finally, add everything in the additions list to the main entity list, and remove everything in the removals list from the main entity list. Then flush those two auxiliary lists so they are ready to be used for the next update.

You're using a separate loop for animation / rendering, so you don't need to worry about including it here, but many people put that in as a final step (which causes issues as Gaffer notes in his article.)

You can also refer to this question for some overview of the order inside your update function.

  • \$\begingroup\$ This is quite helpful, maybe i am going to implement it in a more 'object-oriented' approach. BTW, could you provide a little bit more resources for game loop or frames? I am still learning about it. Thanks a lot. \$\endgroup\$
    – zuo
    Oct 28, 2012 at 11:21
  • \$\begingroup\$ HTH @zuo, have amended it so you've got more to go on. \$\endgroup\$
    – Engineer
    Oct 28, 2012 at 11:47
  • \$\begingroup\$ @zuo Just amended again to clarify how the collision checks are processed, FYI. \$\endgroup\$
    – Engineer
    Oct 28, 2012 at 12:07
  • \$\begingroup\$ For the animation, will it be ok to have another separate loop for a specified sprites-sheet animation, for example, a background animation? \$\endgroup\$
    – zuo
    Oct 28, 2012 at 12:16
  • \$\begingroup\$ @zuo You can, but I suspect it may look better if you keep all the rendering in one loop, or you might notice a discrepancy between background and sprite rendering. It's also a bit easier to manage than splitting out into many loop functions, i.e. it would also be better form, I think. But technically, nothing is stopping you from trying that to see how it looks. \$\endgroup\$
    – Engineer
    Oct 28, 2012 at 12:18

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .