精灵没有动画
Sprites aren't animating
我一直在尝试更新游戏中的敌人精灵,方法是创建一个指向敌人对象的指针向量,然后使用更新函数对属于这些对象的精灵进行动画处理。虽然敌人的精灵显示在屏幕上,但它们不会更新,所以它们看起来就像被冻结了一样。
以下是我编写代码的方式:
#include<iostream>
#include<SFML/Graphics.hpp>
#include<math.h>
#include<vector>
#include<cstdlib>
#include "Enemy.h"
sf::RenderWindow window(sf::VideoMode(1920, 1080), "Zombie game", sf::Style::Default);
std::vector<Enemy*>enemies;
int main()
{
window.setFramerateLimit(60);
sf::Clock clock;
Enemy *enemy = new Enemy();
enemy->init("Assets/graphics/zombieSpriteSheetWalk.png", 4, 1.0f, sf::Vector2f(200.0f, 200.0f), sf::Vector2i(100, 107));
enemies.push_back(enemy);
while (window.isOpen())
{
sf::Event event;
while (window.pollEvent(event))
{
if (event.type == sf::Event::Closed || event.key.code == sf::Keyboard::Escape) window.close();
}
sf::Time dt = clock.restart();
for (int i = 0; i < enemies.size(); i++)
{
Enemy *enemy = enemies[i];
enemy->update(dt.asSeconds());
}
window.clear();
for (Enemy* enemy : enemies) window.draw(enemy->getSprite());
window.display();
}
return 0;
}
敌人.h文件:
#pragma once
#include<SFML/Graphics.hpp>
#include <iostream>
class Enemy
{
public:
Enemy();
~Enemy();
void init(std::string textureName, int frameCount, float animDuration, sf::Vector2f position, sf::Vector2i spriteSize);
void update(float dt);
sf::Sprite& getSprite();
void test();
private:
sf::Texture m_texture;
sf::Sprite m_sprite;
sf::Vector2f m_position;
int m_frameCount; //no. of frames in animation
float m_animDuration; //How long animation lasts (speed)
float m_elapsedTime; //keeps track of how long game has been running
sf::Vector2i m_spriteSize; //Size of each frame
};
敌人.cpp文件:
#include "Enemy.h"
Enemy::Enemy()
{
}
Enemy::~Enemy()
{
}
void Enemy::init(std::string textureName, int frameCount, float animDuration, sf::Vector2f position, sf::Vector2i spriteSize)
{
m_position = position;
m_frameCount = frameCount;
m_animDuration = animDuration;
m_spriteSize = spriteSize;
m_texture.loadFromFile(textureName.c_str());
m_sprite.setTexture(m_texture);
m_sprite.setTextureRect(sf::IntRect(0, 0, m_spriteSize.x, m_spriteSize.y));//sets which part of sprite sheet we want to display
m_sprite.setPosition(m_position);
m_sprite.setOrigin((m_texture.getSize().x / frameCount) - 25.0f, m_texture.getSize().y / 2);
}
void Enemy::update(float dt)
{
m_elapsedTime += dt;
int animFrame = static_cast<int>((m_elapsedTime / m_animDuration) * m_frameCount) % m_frameCount; //calculates current animation frame number. static_class converts float to int
m_sprite.setTextureRect(sf::IntRect(animFrame * m_spriteSize.x, 0, m_spriteSize.x, m_spriteSize.y)); //updates part of sprite sheet to be displayed
}
sf::Sprite& Enemy::getSprite()
{
return m_sprite;
}
你总是在时间 0
从 SFML 时钟标头:
////////////////////////////////////////////////////////////
/// brief Restart the clock
///
/// This function puts the time counter back to zero.
/// It also returns the time elapsed since the clock was started.
///
/// return Time elapsed
///
////////////////////////////////////////////////////////////
Time restart();
可能的修复
- 使用
sf::Clock
表示dt
而不是sf::Time
并将其移出事件循环(您希望它在程序运行时累积,而不是每次都重置为 0。 - 取代:
跟enemy->update(dt.asSeconds());
enemy->update(dt.getElapsedTime());
更多注意事项
我在这个类型的答案中做了一些假设,因为你的例子不完整。您所做的一个重大遗漏是不包括class Enemy
定义(尤其是成员变量的类型(。
根据Enemy::init
的定义,我假设它将包含以下内容:
class Enemy
{
float m_elapsedTime;
float m_animDuration;
int m_frameCount;
...
但是,这些定义会导致您的Enemy::update
版本中出现以下编译错误:
enemy.cpp: In member function ‘void Enemy::update(float)’:
enemy.cpp:14:88: error: invalid operands of types ‘float’ and ‘int’ to binary ‘operator%’
int animFrame = static_cast<int>(((m_elapsedTime / m_animDuration) * m_frameCount) % m_frameCount);
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~
浮
如果游戏时间是浮动的,则您不希望运行作为游戏时间函数的动画。原因是浮点数在不同的值范围内具有不同的精度,数字越接近 0,您拥有的精度就越高,并且您离 0 越远,您的精度就越低。这意味着随着游戏时间的进行,您的动画将不会以恒定的速率运行(经过足够的时间后,它们会显得断断续续、不一致、不流畅(。
更好的方法是有一个包装动画计数器,该计数器将增量时间相加,然后回绕到零(或者可能回绕到 0 + 一些余数,也许使用 fmod 之类的函数(。这将确保您的动画帧速率在整个游戏期间保持一致。
相关文章:
- 在执行其他功能的同时播放动画(LED矩阵和Arduino/ESP8266)
- 使用 GLUT 使用键停止动画?
- 使用对象数组对 SFML 进行动画处理
- 从精灵表在 sfml 中为精灵制作动画
- 精灵动画查看器应该使用哪些Qt小部件
- 精灵没有动画
- 我没有看到精灵的动画
- Cocos2d中精灵的暂停/简历动作/动画
- 精灵表动画 ->滞后?
- 使用OpenGL的2D精灵动画技术
- 在 Cocos2DX 中移动动画精灵和路径
- 使用缩放帧的精灵表动画
- 精灵表动画Cocos2dx
- SDL2 c++捕捉渲染动画/精灵的视频
- 在Cocos2dx中协调多个精灵动画
- SDL动画精灵
- 如何传递一个c++对象变量到Lua脚本,以便动画精灵
- SDL如何在按键时设置精灵的动画
- 如何在 OpenGL 中高效地制作 2D 精灵动画
- 我如何设置一个if语句来动画一个精灵