How do I use delta-times to determine the speed of a frame-by-frame animation?

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.

• What are you using to make the game? any engine or framework? – SanSolo Dec 7 '15 at 12:14
• 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. – 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
anim.curFrame=(anim.curFrame+1)%anim.nFrames
end
end
end
end


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

• if should maybe be while in case of large dt – 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)
draw_frame(frames[frame_nr]);
else
... // 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.