I have a character spritesheet with 8 images. How do I animate it?

At the moment, the sprite changes to a different image every frame, which makes the animation speed vary with framerate. I have a delta time that calculates the time in ms between each frame. Is there a smart way to make sprite animations use it?

I'm using JavaScript and canvas on my own engine, for practice.

  • 1
    \$\begingroup\$ What are you using to make the game? any engine or framework? \$\endgroup\$ – SanSolo Dec 7 '15 at 12:14
  • \$\begingroup\$ I'm writing the game in Javascript using canvas. I'm not using any framework or engine currently, but I'm trying to create my own engine with this. \$\endgroup\$ – Phoenix1355 Dec 7 '15 at 14:02

Assuming pseudo code (in my example I use lua code) , and an anim class , consider the following anim update (using delta time dt) called in your update or draw cicle (it depends on engine..)

function anim:update(dt)
    if anim.started then
        anim.accum = anim.accum+dt          
        while anim.accum > anim.frameTime then
            anim.accum = anim.accum-anim.frameTime
            if anim.aType=="loop"then

where anim.accum is an accumulator initilized to zero. anim.frameTime is the time (ms?) of each frame.(i.e: to increase anim speed reduce anim.frameTime). Anim.curFrame is current frame index (I leave to you how to recover a frame from your spritesheet, given an index, cause it depends on your spritesheet logic). anim.nFrames is animation total frames number.

Edited : thanks to Jon comment

  • 3
    \$\begingroup\$ if should maybe be while in case of large dt \$\endgroup\$ – Jon Mar 20 '16 at 4:24

If you measured the time in ms from the start of the animation, the formula would be:

var frame_nr = Math.floor(FPS * time / 1000);

This way if your time was say 500 [ms] and your FPS was 60, the frame_nr would be 30. You'd need to handle the case when the frame_nr exceeds your animation's length.

If you wanted the animation to loop, you could use the modulo operator:

var frame_nr = Math.floor(FPS * time / 1000) % frames.length;

So at half a second and 60 FPS and 30 frames long animation, the frame_nr would wrap back to 0.

Otherwise, if the animation was to be played just once, before you used a frames_nr to refer to an actual frame, you'd have to test for:

if (frame_nr < frames.length)
    ... // animation ended

Finally, to measure time you'd have to initialize the variable to 0 when your animation starts, and then at each frame accumulate the delta you already have available.


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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