Take the 2-minute tour ×
Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

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?

share|improve this question
add comment

1 Answer

up vote 2 down vote accepted

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 ANIMATION_FREQ = 33;
var ANIMATION_PERIOD = 1000 / ANIMATION_FREQ;
var LOGIC_FREQ = 10;
var LOGIC_PERIOD = 1000 / LOGIC_FREQ;

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.

share|improve this answer
    
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. –  zuo Oct 28 '12 at 11:21
    
HTH @zuo, have amended it so you've got more to go on. –  Nick Wiggill Oct 28 '12 at 11:47
    
@zuo Just amended again to clarify how the collision checks are processed, FYI. –  Nick Wiggill Oct 28 '12 at 12:07
    
For the animation, will it be ok to have another separate loop for a specified sprites-sheet animation, for example, a background animation? –  zuo Oct 28 '12 at 12:16
    
@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. –  Nick Wiggill Oct 28 '12 at 12:18
show 1 more comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.