如何在sfml中制作玩家动画?

  • 本文关键字:玩家 动画 sfml c++ sfml
  • 更新时间 :
  • 英文 :


我想让玩家更真实一些,而不是像幽灵一样徘徊。这是我的代码只是一些基本的重力和运动,我想做跳跃动画,行走动画,左转和右转动画。我怎么做呢?

下面代码:

void Game::initTexture()
{
if (!texture.loadFromFile("/home/webmaster/Documents/vscode-sfml/src/Ball_and_Chain_Bot/pixil-frame-0(1).png"))
{
std::cout << "failed to load texturen";
rect.setTexture(texture);
rect.setPosition(this->window->getView().getCenter());
rect.setScale(2,2);
}
}

呈现:

void Game::render()
{
this->window->clear(sf::Color(239, 235, 216));
this->window->draw(rect);
this->window->display();
}

您忘记显示您的实际代码,标题不是很有用。不管:

  1. 定义一些动画。每个动画都应该有一个目标长度和覆盖该目标的帧数。一开始,让每一帧都一样长是最容易的,但没有人会阻止你让第一帧花0.2秒,第二帧0.8秒,第三帧0.15秒。
  2. 添加代码来跟踪"当前动画";在适当的时间尺度上正确地循环帧(即如果你有4帧,目标为15秒,则显示每帧0.25秒)。有些动画可能会循环,例如"运行"。或";idle"动画。存储动画的一种常用技术是"纹理图集"。它包含动画的所有帧。然后你可以使用sf::Shape::setTextureRect选择纹理的一部分来绘制。
  3. 更新你的移动和输入代码来改变动画,如果角色的状态改变

让我们根据给定精灵表的sf::IntRect部分来定义动画帧:(以精灵表为例)

std::vector<sf::IntRect> idle {
{0, 0, 35, 61}
};
std::vector<sf::IntRect> runningRight {
{657, 473, 43, 52}, // first frame is at 657x473 and is 43x52 pixels
// other frames.
};

我们可以用以下数据和方法定义一个Animation类:

class Animation {
public:
Animation(const std::vector<sf::IntRect>& frames, float duration, bool cycles = true) : frames(frames), frameTime(duration / frames.size()), cycles(cycles) { reset(); }
void reset() {
currentFrame = 0;
currentFrameTime = 0;
}
void update(float dt);
const sf::IntRect& getCurrentRect() const { return frames[currentFrame]; }
private:
const std::vector<sf::IntRect>& frames;
const float frameTime;
bool cycles;
int currentFrame;
float currentFrameTime;
};

这实现了大部分的步骤2:保持跟踪哪一帧应该在屏幕上,假设update(dt)被调用每一帧。

现在剩下的就是update方法了:

void Animation::update(float dt) {
currentFrameTime += dt;
// TODO: take `cycles` into account.
while (currentFrameTime >= frameTime) {
currentFrameTime -= frameTime;
currentFrame = (currentFrame + 1) % frames.size();
}
}

最后,要将其连接起来,创建以下变量:

sf::Texture textureAtlas = ...;
Animation currentAnimation{idle, 10.0f};
sf::Sprite player(textureAtlas, currentAnimation.getCurrentRect());

  • 在游戏的update()代码中,调用currentAnimation.update(dt)
  • 在渲染函数中,确保调用player.setTextureRect(currentAnimation.getCurrentRect())
  • 如果您收到输入,请执行currentAnimation = Animation{runningRight, 1.0f};

最新更新