A Main Loop Suitable for Stable Animations

I was recently asked how to have objects that animate themselves (change frames) in a stable way that isn't dependent on the FPS or lag of the device. There are many ways to do this but I have a simple one which uses the difference between the last tick and the current tick to count down. My example is in Java and is suitable for most games. The first step is to use a main loop which gives the updates that info. The best way to do this is to give every thing that is updating the exact same time information and have them all use that.

Use a basic World class that holds the state of everything, including the tick time information.

Find any rogue calls to System.currentTimeMillis() and change them to use world.curTickMs

This update() method is what I call from run() in a loop in the Thread.

/**
* The Main Update routine
*
* @return
*/
private boolean update() {
if (!isPaused) {
long now = System.currentTimeMillis();
if (now - lastTick > TICK_DELAY) {
world.lastTickMs = lastTick;
world.curTickMs = now;
world.tickDelta = now - lastTick;
lastTick = now;
updatePlayerPhysics();
updateItems();
updateState();
return true;
}
}
return false;
}

After that, the animations can be done in one of the update() calls and they can do something like this:

private static final int FRAME_DELAY = 100; // 100ms between frame changes
private static final int FRAMES = 20; // 20 frames in this animation
private int delayRemainder = FRAME_DELAY;
private int currentAnimationFrame = 0;

public void updateAnimation(World world) {
delayRemainder -= world.tickDelta;
if (delayRemainder < 0) {
currentAnimationFrame++;
delayRemainder = FRAME_DELAY;
if (currentAnimationFrame > FRAMES) {
currentAnimationFrame = 0;
}
}
}

public void draw(Canvas canvas) {
//draw bitmap for currentAnimationFrame
}

There are other ways to do this but this method works well because it uses world time and can pause the animation, provided that the main loop resets the lastTick and Tick Delta on pause.

1 Comment

Post a comment here or discuss this and other topics in the forums

Thanks SOO much! I love it

Thanks SOO much! I love it

Post new comment

The content of this field is kept private and will not be shown publicly.
Add image
  • Web page addresses and e-mail addresses turn into links automatically.
  • Allowed HTML tags: <a> <em> <strong> <cite> <code> <ul> <ol> <li> <dl> <dt> <dd> <table> <tr> <td>
  • Lines and paragraphs break automatically.
  • Images can be added to this post.
  • Image links with 'rel="lightbox"' in the <a> tag will appear in a Lightbox when clicked on.
  • Image links with 'rel="lightshow"' in the <a> tag will appear in a Lightbox slideshow when clicked on.
  • Links to HTML content with 'rel="lightframe"' in the <a> tag will appear in a Lightbox when clicked on.
  • Links to video content with 'rel="lightvideo"' in the <a> tag will appear in a Lightbox when clicked on.
  • Links to inline or modal content with 'rel="lightmodal"' in the <a> tag will appear in a Lightbox when clicked on.

More information about formatting options

CAPTCHA
This question is for testing whether you are a human visitor and to prevent automated spam submissions.