Most of this week has for my part been taken up by getting the Thor library extension for SFML to work properly. Thor is made to provide options for 2D animation with SFML, allowing sprites to be animated. While it took quite some time to figure out, once I got it to work the process Thor uses is easy to replicate. Even so, installing the library was a confusing mess and the online instructions were more or less awful. In the end I got a copy of the correct files sent over by a classmate, which worked just fine after some fixing of missing files.
Once Thor was operational, began trying to figure out how to use it. As mentioned I found the online tutorial to be a confusing mess, so I had to ask around and do quite a bit of trial and error. What I could deduce online was two of the main functions of Thor: thor::Animator and thor::FrameAnimation.
thor::FrameAnimation Is used to put in frame, while thor::Animator puts those together and turns them into displayable animations. To do this you need a sprite sheet with the different frames of the animation for the functions to work with. The sprite sheet for our diver’s animations that I got from our art person looks like this:
Using thor’s functions, I then set up so that the Animator jumps between each of these frames in the correct order, which for arcane reasons is not the order they are displayed in. thor::Animator then makes sure to show the frames one by one, keeping the active one as the sprite of the player. Now let us see how the code is set up:
//Player.hpp
public:
thor::Animator <sf::Sprite, std::string> *getAnimator();
thor::FrameAnimation &getAnimation();
private:
thor::Animator<sf::Sprite, std::string>* m_animator;
thor::FrameAnimation swim;
As seen here I have given the player class two functions in public, which will be used to return the animator and the animation. Next there are two features in private which are used to create the animation itself. Now let us go over the the player.cpp file:
void Player::Initialize()
{
m_sprites[0].first->setOrigin(m_sprites[0].first->getLocalBounds().width * .5f, m_sprites[0].first->getLocalBounds().height * .5f);
thor::FrameAnimation swim;
m_animator = new thor::Animator<sf::Sprite, std::string>;
swim.addFrame(1.f, sf::IntRect(0, 0, 256, 256));
swim.addFrame(1.f, sf::IntRect(256, 0, 256, 256));
swim.addFrame(1.f, sf::IntRect(0, 256, 256, 256));
swim.addFrame(1.f, sf::IntRect(256, 256, 256, 256));
swim.addFrame(1.f, sf::IntRect(512, 0, 256, 256));
swim.addFrame(1.f, sf::IntRect(512, 256, 256, 256));
swim.addFrame(1.f, sf::IntRect(768, 0, 256, 256));
swim.addFrame(1.f, sf::IntRect(768, 256, 256, 256));
swim.addFrame(1.f, sf::IntRect(0, 512, 256, 256));
swim.addFrame(1.f, sf::IntRect(0, 768, 256, 256));
m_animator->addAnimation(”swim”, swim, sf::seconds(1.8f));
m_animator->playAnimation(”swim”, true);
m_animator->animate(*m_sprites[0].first);
}
First we make sure the sprite will be centralized using the setOrigin command. Once that is done we create the thor::FrameAnimation called swim. We also set up m_animator’s value for future use. Next we add the frames to swim one by one, using sf::intRect to decide which part of the sprite sheet each frame uses. We here have ten frames that uses each of the diver sprites in the sheet. The add animation function is then used to add all the frames into the animator and decide the numbers of seconds that the animation will take. We also declare the that it shall play the animation, and use Player’s main sprite to do so.
Next up we go to update, where we find the following:
m_animator->update(sf::seconds(deltatime));
m_animator->animate(*m_sprites[0].first);
m_sprites[0].first->setOrigin(m_sprites[0].first->getLocalBounds().width * .5f, m_sprites[0].first->getLocalBounds().height * .5f);
The first thing done by m_animator is that it takes into account the seconds passed according to update’s deltatime, and co-ordinates the animation after it. Then m_animator sees over the animation and updates the sprite if need be. Finally the sprite makes sure that the center of the current sprite is equal to origin. The final bit is more to solve possible issues before they happen, and might not be essential.
Based on this, we get the result of an animated sprite:
So to finish this up. While the results is what I wanted, the amount of work it took to install Thor and figure out how it works means that in the end I do not feel like it is worth recommending. If you desperately need a extension for animation Thor does work, but be prepared on that the installation will be a confusing and ill-explained process. Hopefully this read was not too tedious.
/Stefan
Where to find Thor: http://www.bromeon.ch/libraries/thor/