🎉 Celebrating 25 Years of GameDev.net! 🎉

Not many can claim 25 years on the Internet! Join us in celebrating this milestone. Learn more about our history, and thank you for being a part of our community!

Stable animation system that doesn't desynchronize over time?

Started by
6 comments, last by nilkun 4 years, 9 months ago

This is the first game of mine where animations were strongly linked to the game logic (not code-wise, I meant it's as hints to the player), and I have realized that I've been doing animations wrong this whole time, for my code before was (in pseudo-pseudo-code):


Rect Animation::update(float delta) {
	if(playing) {
		frame = fmodf(frames + frame + delta * fps, frames);
	}
	
	return /* calculate sprite in spritesheet with `frame`. */;
}

Now, some would probably immediately realize that `delta` here is imprecise. At, say, a framerate of 60fps, delta would equal `0.016667`. In one real second that would all add up to `1.00002`, not `1`!

I thought about calculating the frame number with something more stable, such as `SDL_GetTicks()` in SDL2, but doing it this way makes pausing the animation more difficult (Unless I'm wrong here, which I hope in this case).

Another question, since animations are important for gameplay, and thus they must be synchronized, I thought about setting animation delta to the game timestep (1 / 60 in this case), would that be a good idea or would that be noticeable?

Advertisement

Perhaps it's easier to control if you just wait for a certain time to pass before advancing to the next animation frame. There is no need to calculate it all the time when it doesn't change.

Obviously a frame index would be an integer and not a float.

There is no waiting system in the engine, and said waiting system could have the exact same problems.

What do you mean by 'waiting system'? You can check your delta and if it is lower than some treshold, you exit the function. Otherwise you increase the frame index, preferably using an integer. Float makes no sense for an index and will lead to this kind of errors and worse.

I don't see what other problems you are having, otherwise you have to explain how your animation is so rigidly tied to the game logic.

Using ticks is the way to go (we use something similar to Facebook's Flicks https://en.wikipedia.org/wiki/Flick_(time)).

We calculate the `delta` inside the animation system - it stores the last update ticks internally. Pausing the animation is easy - you just set the delta to be always 0. Resuming is also straightforward - you set `lastUpdateTicks` to the current time and on the first frame after resuming, the delta will be a very small number (or 0, depending on where you react to `Resume` commands), resulting in a smooth animation.

 

 

I am already using ticks, that's what I meant by fixed timestep.

I seemed to have a brainderp, though, didn't think to use it for the animation system. I'll message back if I have even more problems.

I think you are looking for something like this? (currentFrame is a floating point number)

 


currentFrame = (currentFrame + delta * playbackSpeed) % noOfFrames;
showFrame((int) currentFrame);

 

– Lover of 8-bits before it was hi-tech --

This topic is closed to new replies.

Advertisement