我想让玩家更真实一些,而不是像幽灵一样徘徊。这是我的代码只是一些基本的重力和运动,我想做跳跃动画,行走动画,左转和右转动画。我怎么做呢?
下面代码:
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();
}
您忘记显示您的实际代码,标题不是很有用。不管:
- 定义一些动画。每个动画都应该有一个目标长度和覆盖该目标的帧数。一开始,让每一帧都一样长是最容易的,但没有人会阻止你让第一帧花0.2秒,第二帧0.8秒,第三帧0.15秒。
- 添加代码来跟踪"当前动画";在适当的时间尺度上正确地循环帧(即如果你有4帧,目标为15秒,则显示每帧0.25秒)。有些动画可能会循环,例如"运行"。或";idle"动画。存储动画的一种常用技术是"纹理图集"。它包含动画的所有帧。然后你可以使用
sf::Shape::setTextureRect
选择纹理的一部分来绘制。 - 更新你的移动和输入代码来改变动画,如果角色的状态改变
让我们根据给定精灵表的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)
。 在渲染函数中,确保调用 - 如果您收到输入,请执行
currentAnimation = Animation{runningRight, 1.0f}
;
player.setTextureRect(currentAnimation.getCurrentRect())
。