I've been trying to animate an sf::Sprite with Thor 2.1, but as of now my sprite only displays one frame of each animation, not going through all of them.
I've got a sample spritesheet out of one of SFML's tutorials for spritesheets:
My code (schematic code, not the whole):
#include<SFML/Window.hpp>
#include<SFML/Audio.hpp>
#include<SFML/Graphics.hpp>
#include<SFML/System.hpp>
#include<SFML/Main.hpp>
#include<stdlib.h>
#include<iostream>
#include <Thor/Animations.hpp>
int main()
{
sf::Texture texPlayer;
texPlayer.create(96, 128);
if (!texPlayer.loadFromFile(workingDirectory + "\\textures\\animtest.png"))
{
std::cout << "can't load" << std::endl;
}
sf::Sprite sprPlayer;
sprPlayer.setTexture(texPlayer);
thor::FrameAnimation playerDown;
playerDown.addFrame(10.0f, sf::IntRect(0 , 0, 32, 32));
playerDown.addFrame(10.0f, sf::IntRect(32, 0, 32, 32));
playerDown.addFrame(10.0f, sf::IntRect(64, 0, 32, 32));
thor::FrameAnimation playerLeft;
playerLeft.addFrame(20.0f, sf::IntRect(0 , 32, 32, 32));
playerLeft.addFrame(20.0f, sf::IntRect(32, 32, 32, 32));
playerLeft.addFrame(20.0f, sf::IntRect(64, 32, 32, 32));
thor::FrameAnimation playerRight;
playerRight.addFrame(30.0f, sf::IntRect(0 , 64, 32, 32));
playerRight.addFrame(30.0f, sf::IntRect(32, 64, 32, 32));
playerRight.addFrame(30.0f, sf::IntRect(64, 64, 32, 32));
thor::FrameAnimation playerUp;
playerUp.addFrame(40.0f, sf::IntRect(0 , 96, 32, 32));
playerUp.addFrame(40.0f, sf::IntRect(32, 96, 32, 32));
playerUp.addFrame(40.0f, sf::IntRect(64, 96, 32, 32));
thor::AnimationMap<sf::Sprite, std::string> playerAMap;
playerAMap.addAnimation("down" , playerDown , sf::seconds(2.0f));
playerAMap.addAnimation("left" , playerLeft , sf::seconds(3.0f));
playerAMap.addAnimation("right", playerRight, sf::seconds(4.0f));
playerAMap.addAnimation("up" , playerUp , sf::seconds(5.0f));
thor::Animator<sf::Sprite, std::string> playerAnimator = thor::Animator<sf::Sprite,
std::string>::Animator(playerAMap);
sf::Clock animFrameTime;
sf::RenderWindow window;
window.create(sf::VideoMode(800, 450), "Placeholder", sf::Style::Default);
while (window.isOpen())
{
// here's movement direction checking, event handling, dealing with movement overall
// let's say we dont use any of that now and we want to play just the "up" animation
playerAnimator.play() << "up" << thor::Playback::loop("up");
playerAnimator.update(animFrameTime.restart());
playerAnimator.animate(sprPlayer);
window.draw(sprPlayer);
}
return 0;
}
As I said, the behaviour of that code is it just plays the first frame of up animation (in this case the upper-left frame of the spritesheet).
For "left" animation it plays the first frame of the second row, and for all the others respectively.

First,
is not needed, as you immediately load a file and thus overwrite the texture.
sf::Texture::create()is mainly useful when you edit the texture after loading it, or use it for low-level OpenGL.The
thor::Animatorcan be understood to have two modes of operation, each of which covers a few methods:play(),stop(),queue()This should be invoked only when you want to change the animation playing (a character starts to move/attack) or when you want to stop a playing animation (character stands still).
update(),animate()This should be applied every graphics frame. If you want deterministic animation behavior (your animations require constant progress), you should call
update()in a fixed-time logic step.Those are already all the methods that
thor::Animatoroffers, see official documentation.The mistake in your code is that you call
play()in every frame, thus restarting the animation constantly. What you should do instead is callplay()before thewhileloop. Since you specifiedthor::Playback::loop(), the animation will be looping as long as you update the animator.