C++ SFML 精灵运动无法按预期工作

C++ SFML Sprite movement not working as intended

本文关键字:工作 SFML 精灵 运动 C++      更新时间:2023-10-16

我正在使用带有C++的SFML来尝试移动应用了某种纹理的精灵,但它并没有像我想要的那样移动。

我是SFML的新手,我在sfml网站上阅读了有关运动的教程,并在Youtube上观看了许多有关此的教程。我看到的东西要么非常基础,要么目前足够复杂(主要是游戏开发的东西)

#include <SFML/Graphics.hpp>
#include <thread>
#include <chrono>
#include<iostream>
using namespace sf;
using namespace std;
int main()
{
sf::RenderWindow window(sf::VideoMode(600, 600), "test!");
Texture t;
t.loadFromFile("/*texture directory*/");
Sprite s(t);
s.setScale(Vector2f(0.25f, 0.25f));
float temp = 0;
while (window.isOpen())
{
sf::Event event;
while (window.pollEvent(event))
{
if (event.type == sf::Event::Closed)
window.close();
}
window.clear(Color::White);
window.draw(s);
window.display();
s.move(Vector2f(temp, temp));

for (int i = 0; i < 3; i++) {
if (i == 0) {
this_thread::sleep_for(chrono::milliseconds(1000));
temp = 10;
}
else if (i == 1) {
this_thread::sleep_for(chrono::milliseconds(1000));
temp = 20;
}
else {
this_thread::sleep_for(chrono::milliseconds(1000));
temp = -10;
}
}
}
return 0;
}

我希望精灵移动到 (10,10),然后在一秒钟后移动到 (20,20),然后在一秒钟后,移回 (10,10)。 相反,子画面每三秒仅移动 (-10,-10),因此它只在循环结束时获取 temp 的值。 同样的事情也适用于setPosition。

这里有一些非常基本的东西在起作用,但研究让我得到的问题比答案更多,这就是我来到这里的原因。

最外层的while循环管理绘图。你在其中放了另一个for循环。内部循环必须先完成,然后外部循环才能继续其迭代,即绘制另一个帧。执行不会异步发生,因此具有std::this_thread::sleep_for调用的for循环总共会阻塞渲染循环 3 秒。它使它更改为temp,这是无条件-10在最后。

相反,您要做的是创建通过渲染循环持续存在的状态,并创建一个小型状态机。此状态将是您的i。在temp附近声明并初始化它(好吧,您也可以在if语句中使用temp)并删除for循环。如果要继续动画,请不要忘记在将temp设置为-10i设置回0

另一种可能但较差的方法是:

  1. 将渲染(以及可能的事件处理)代码放入函数中;
  2. 每次您希望
  3. 刷新图形时调用此函数,即每次设置temp后,但请记住事先更新s

最后,我相信sf::Sprite具有访问状态的成员功能,而不仅仅是修改,因此您应该能够仅使用s,而不需要temp。保持简单,并从控制流的角度思考。

避免在渲染线程上使用睡眠。

相反,您将测量经过的时间并按比例移动:

#include <SFML/Graphics.hpp>
#include <thread>
#include <chrono>
#include<iostream>
using namespace sf;
using namespace std;
int main()
{
sf::RenderWindow window(sf::VideoMode(600, 600), "test!");
Texture t;
t.loadFromFile("/*texture directory*/");
Sprite s(t);
s.setScale(Vector2f(0.25f, 0.25f));
float speed = 10.0;
sf::Clock clock;
while (window.isOpen())
{
sf::Event event;
while (window.pollEvent(event))
{
if (event.type == sf::Event::Closed)
window.close();
}
float time = clock.getElapsedTime().asSeconds();
s.move(Vector2f(speed*time, speed*time));
clock.restart();
window.clear(Color::White);
window.draw(s);
window.display();

}
return 0;
}

此代码允许你的精灵移动到固定速度。您可以使用额外的 sf::clock 更改速度