C++ SFML Sprite 运动没有按预期工作
C++ SFML Sprite movement not working as intended
我正在使用带有 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
循环。内部循环必须完成,然后外部循环才能继续其迭代,即绘制另一帧。执行不会异步发生,因此您的 for
循环与 std::this_thread::sleep_for
调用会阻塞渲染循环总共 3 秒。它使它变为temp
,最后无条件地-10
。
您想要做的是创建 state,它在渲染循环中持续存在并制作一个小状态机。这个状态将是你的i
。在 temp
附近声明并初始化它(好吧,您也可以在 if
语句中使用 temp
)并删除 for
循环。如果您希望继续播放动画,请不要忘记在将 temp
设置为 -10
时将 i
设置回 0
。
另一种可行但较差的方法是:
- 将渲染(以及可能的事件处理)代码放入一个函数中;
- 每次您希望刷新图形时调用此函数,即在每次设置
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
来改变速度
我正在使用带有 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
循环。内部循环必须完成,然后外部循环才能继续其迭代,即绘制另一帧。执行不会异步发生,因此您的 for
循环与 std::this_thread::sleep_for
调用会阻塞渲染循环总共 3 秒。它使它变为temp
,最后无条件地-10
。
您想要做的是创建 state,它在渲染循环中持续存在并制作一个小状态机。这个状态将是你的i
。在 temp
附近声明并初始化它(好吧,您也可以在 if
语句中使用 temp
)并删除 for
循环。如果您希望继续播放动画,请不要忘记在将 temp
设置为 -10
时将 i
设置回 0
。
另一种可行但较差的方法是:
- 将渲染(以及可能的事件处理)代码放入一个函数中;
- 每次您希望刷新图形时调用此函数,即在每次设置
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
来改变速度