matt-hayward / olcPGEX_AnimatedSprite

Easily use animated sprites in the OLC Pixel Game Engine
22 stars 4 forks source link

Erronous playback of a 2-frame animation #26

Open RustKnight opened 3 years ago

RustKnight commented 3 years ago

Describe the bug When trying to play an animation composed of 2-frames only, (yes, a really short animation :) ), it will play correctly once, but then get stuck on the first frame. With PING-PONG mode.

NOTICE: I've only tested this with a spreadsheet, but I suspect the code with this bug is also used in other parts of the PGE plugin.

REASON: Inspecting the olc::vi2d AnimatedSprite::GetSingleFrame(float fElapsedTime) function we can see that:

if (currentFrame >= singleFrames[state].size()) {
currentFrame = playModes[state] == PLAY_MODE::LOOP ? 0 : singleFrames[state].size() -2; playForward = false; }

-2 is used so that when the animation reaches the end, it does not play the same end frame, and starts with the before-end frame. In a 2-frame animation scenario, this means: currentFrame = size()<which is 1 in our case> - 2 = -1

When we come back to the GetSingleFrame function, the check if (currentFrame >= singleFrames[state].size()) will pass because it is comparing a signed int with an unsigned int, even if currentFrame is -1.

At this point the animation is stuck to play forever it's first frame.

A quick/naive solution I did was to cast singleFrames to an int so that the comparison does not pass true with -1 >= 1 . I also changed -2 to -1, but that means in a ping-pong scenario that we play 2 times the end frame. (once when we reached the end, and one more time when we ping-pong back).

matt-hayward commented 3 years ago

I would think that, for a 2-frame animation, you'd use PLAY_MODE::LOOP - ping pong doesn't make sense in that use case.

Perhaps an additional check can be added, though, to basically bypass the ping pong mode if the animation has less than 3 frames, so it behaves the same as loop mode.

I'll take a look into this.

RustKnight commented 3 years ago

You're right! I think initially I tested an animation with more frames with ping-pong playstyle, but then for some reason shrunk the frames to 2 frames.

On the other hand, it does induce some confusing behavior, if the user for some reason had 2 frames and ping-pong on, being stuck on the first frame.