thor::Animator 只播放一帧

thor::Animator playing only one frame

我一直在尝试使用雷神 2.1 为 sf::Sprite 制作动画,但截至目前,我的 sprite 只显示每个动画的一帧,而不是遍历所有动画。

我从 SFML 的 spritesheets 教程中得到了一个示例 spritesheet:

我的代码(原理图代码,不全):

#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;
}

正如我所说,该代码的行为是它只播放向上动画的第一帧(在本例中是 spritesheet 的左上帧)。

对于 "left" 动画,它播放第二行的第一帧,并分别播放所有其他帧。

首先,

texPlayer.create(96, 128);

不需要,因为您会立即加载文件并因此覆盖纹理。 sf::Texture::create() 主要用于加载后编辑纹理,或用于低级 OpenGL。

thor::Animator可以理解为有两种操作模式,每一种都涵盖了几个方法:

  • Select/switch 动画: play(), stop(), queue()
    仅当您想要更改正在播放的动画(角色开始 move/attack)或想要停止正在播放的动画(角色静止不动)时才应调用此方法。
  • 更新状态并应用图形: update(), animate()
    这应该应用于每个图形帧。如果你想要确定性的动画行为(你的动画需要不断的进步),你应该在固定时间的逻辑步骤中调用 update()

这些已经是thor::Animator提供的所有方法,参见official documentation

您的代码中的错误是您在每一帧都调用了 play(),从而不断地重新启动动画。您应该做的是在 while 循环之前调用 play()。由于您指定了 thor::Playback::loop(),只要您更新动画器,动画就会循环播放。