Hello all!
After a long hiatus, I decided to continue with SFML, and since I needed a simple animation system, I decided to use
this one from the wiki. I made some minor modifications to get it to work with SFML2, but I don't think that this is the problem.
My first test animation was a picture consisting of 20 frames, each frame is of size 192 x 192. It worked great.
Then, I tried to animate a player sprite from RPG Maker VX. The sprite sheet consist of 12 sprites, each frame is of size 32 x 32. This one doesn't seems to work as it supposed to.
First, I tried to animate this part only (the first 3 frames of the sheet, so I set 0 as the starting frame and 2 as the end frame).
Normally, it should go in this order from left to righ (0-1-2). But for some reason, it plays in 0-2-1 order. No matter what I set the start/stop frames to, the animation order will be messed up.
The other problem is, when I don't specify the start and the end frame, and just let the system play the whole sheet, it will somehow add an extra frame, consisting of a 3-pixels wide, and 32 pixels tall vertical bar. This happens when the final frame has been reached, and before the system loops back to the first frame.
Again, neither of these problems happen with larger images (for example, with the one that consist of 192 x 192 frames). But I have no idea why is this happening.
Even if my code is largely the same as in the wiki, I post it here, since I could have been made a mistake.
Here's Animation.h:
#ifndef ANIMATION_H
#define ANIMATION_H
#include <SFML\Graphics.hpp>
class AnimSprite : public sf::Sprite
{
public:
AnimSprite();
AnimSprite(const sf::Texture &img, int frameWidth, int frameHeight);
~AnimSprite();
sf::IntRect AnimSprite::getFramePosition(int frame);
int getFrameCount();
void setFrameSize(int frameW, int frameH);
void setFrame(int frame);
void setLoopSpeed(float newfps);
void play();
void play(int start, int end);
void stop();
void update();
private:
sf::Clock animClock;
float fps;
bool isPlaying;
int loopStart;
int loopEnd;
int currentFrame;
int frameWidth;
int frameHeight;
};
#endif
And here's Animation.cpp:
#include "Animation.h"
AnimSprite::AnimSprite(void) : sf::Sprite()
{
this->fps = 1;
this->currentFrame = 0;
this->loopStart = 0;
this->isPlaying = false;
this->setFrameSize(0, 0);
}
AnimSprite::AnimSprite(const sf::Texture &img, int frameWidth, int frameHeight) : sf::Sprite(img)
{
this->fps = 1;
this->currentFrame = 0;
this->loopStart = 0;
this->isPlaying = false;
this->setFrameSize(frameWidth, frameHeight);
}
AnimSprite::~AnimSprite() { }
int AnimSprite::getFrameCount()
{
unsigned int horizontal = (this->getTexture()->getSize().x / this->frameWidth);
unsigned int vertical = (this->getTexture()->getSize().y / this->frameHeight);
return horizontal * vertical;
}
sf::IntRect AnimSprite::getFramePosition(int frame)
{
unsigned int horizontal = (this->getTexture()->getSize().x / this->frameWidth);
unsigned int vertical = (this->getTexture()->getSize().y / this->frameHeight);
int tileY = frame / horizontal;
int tileX = frame % horizontal;
sf::IntRect result(
tileX * this->frameWidth,
tileY * this->frameHeight,
this->frameWidth,
this->frameHeight);
return result;
}
void AnimSprite::setFrameSize(int frameW, int frameH)
{
this->frameWidth = frameW;
this->frameHeight = frameH;
this->setTextureRect(sf::IntRect(0, 0, frameW, frameH));
}
void AnimSprite::setFrame(int frame) { this->currentFrame = frame; }
void AnimSprite::setLoopSpeed(float newfps) { this->fps = newfps; }
void AnimSprite::play() { this->play(0, getFrameCount()); }
void AnimSprite::play(int start, int end)
{
loopStart = start;
loopEnd = end;
currentFrame = start;
isPlaying = true;
animClock.restart();
}
void AnimSprite::stop() { isPlaying = false; }
void AnimSprite::update()
{
if(isPlaying)
{
int frameCount = (loopEnd + 1) - loopStart;
float timePosition = (animClock.getElapsedTime().asSeconds() * fps);
currentFrame = loopStart + (int)timePosition % frameCount;
this->setTextureRect(getFramePosition(currentFrame));
}
}
Anybody knows what's going on here? Your help would be greatly appreciated. (I believe it's a trivial problem, but I fail to locate it... :S)
EDIT: Okay, I realized it's a bit hard to understand what the problem is, so
here's a compiled binary with the full source code.