使用循环在 C++ 中移动 Sprite (SFML)
Moving Sprite (SFML) in c++ using Loops
我是 c++ 和 SFML 的新手。我正在尝试使用循环使我的精灵对象相对于其最后位置向下移动。我正在寻找程序启动时精灵对象掉落的动画。
我认为在我的 for 循环中实现睡眠函数将有助于解决我遇到的问题,即程序只会在循环的最后一次迭代时显示对象。但是我的程序只是冻结和崩溃。
寻找方向。也许在这里调用 sleep 函数不合适?
#include <SFML/Graphics.hpp>
#include <Windows.h>
#include <iostream>
using namespace std;
int main()
{
// Create the window here. Calling out the dimensions
sf::RenderWindow window(sf::VideoMode(800, 600), "Example Window");
// run the program as long as the window is open
while (window.isOpen())
{
sf::Event event;
while (window.pollEvent(event))
{
//close window we requested
if (event.type == sf::Event::Closed)
{
window.close();
}
}
window.clear(sf::Color::Black);
sf::Texture texture;
if (!texture.loadFromFile("c:\abstract.png"))
{
cout<<"Failed to load image...";
}
sf::Sprite sprite;
sprite.setTexture(texture);
sprite.setTextureRect(sf::IntRect(20,20,30,30));
for (float i = 0; i < 30.; i++)
{
sprite.move(sf::Vector2f(5.f, i));
window.draw(sprite);
Sleep(50);
}
window.display();
}
return 0;
}
您在 for
中所做的是:处理、绘图、处理、绘图...最后显示您使用 window.display()
绘制的内容。
这意味着每帧 window 上显示的内容是 "Processing, drawing" 的结果,换句话说,是精灵在不同位置的 30 倍。
你想要的是每帧移动你的精灵一点。因此,您必须完成当前的 while (window.isOpen())
迭代才能移动精灵、绘制它并显示它,如此反复。
你应该做的是在你的游戏循环之外声明你的精灵(即 while (window.isOpen())
),然后将它移动到这个循环中。
一步一步,您的程序应该如下所示:
- [开始]
- 初始化你的上下文
- 创建精灵
- 开始循环
- 清除屏幕
- 收集输入
- 移动你的精灵
- 画出你的精灵
- 在 window
上显示您的绘图
- 结束循环
- [退出]
您需要处理的最后一件事是 deltaTime(时间步长)。因为如果你每帧从 (x,y) 移动你的精灵,这意味着你的计算机速度越快(能够快速渲染大量帧),你的精灵移动得越快。为了解决这个问题,你必须考虑当前帧和前一帧之间经过的时间来移动你的精灵(你的电脑越慢,你的精灵在一帧中移动的越多,你的电脑越快,你的精灵在一帧中移动的越少)。 Timestep 将使您的精灵每秒移动 (x,y) 而不是每帧移动 (x,y),这正是您在大多数图形应用程序中所需要的。
我是 c++ 和 SFML 的新手。我正在尝试使用循环使我的精灵对象相对于其最后位置向下移动。我正在寻找程序启动时精灵对象掉落的动画。
我认为在我的 for 循环中实现睡眠函数将有助于解决我遇到的问题,即程序只会在循环的最后一次迭代时显示对象。但是我的程序只是冻结和崩溃。
寻找方向。也许在这里调用 sleep 函数不合适?
#include <SFML/Graphics.hpp>
#include <Windows.h>
#include <iostream>
using namespace std;
int main()
{
// Create the window here. Calling out the dimensions
sf::RenderWindow window(sf::VideoMode(800, 600), "Example Window");
// run the program as long as the window is open
while (window.isOpen())
{
sf::Event event;
while (window.pollEvent(event))
{
//close window we requested
if (event.type == sf::Event::Closed)
{
window.close();
}
}
window.clear(sf::Color::Black);
sf::Texture texture;
if (!texture.loadFromFile("c:\abstract.png"))
{
cout<<"Failed to load image...";
}
sf::Sprite sprite;
sprite.setTexture(texture);
sprite.setTextureRect(sf::IntRect(20,20,30,30));
for (float i = 0; i < 30.; i++)
{
sprite.move(sf::Vector2f(5.f, i));
window.draw(sprite);
Sleep(50);
}
window.display();
}
return 0;
}
您在 for
中所做的是:处理、绘图、处理、绘图...最后显示您使用 window.display()
绘制的内容。
这意味着每帧 window 上显示的内容是 "Processing, drawing" 的结果,换句话说,是精灵在不同位置的 30 倍。
你想要的是每帧移动你的精灵一点。因此,您必须完成当前的 while (window.isOpen())
迭代才能移动精灵、绘制它并显示它,如此反复。
你应该做的是在你的游戏循环之外声明你的精灵(即 while (window.isOpen())
),然后将它移动到这个循环中。
一步一步,您的程序应该如下所示:
- [开始]
- 初始化你的上下文
- 创建精灵
- 开始循环
- 清除屏幕
- 收集输入
- 移动你的精灵
- 画出你的精灵
- 在 window 上显示您的绘图
- 结束循环
- [退出]
您需要处理的最后一件事是 deltaTime(时间步长)。因为如果你每帧从 (x,y) 移动你的精灵,这意味着你的计算机速度越快(能够快速渲染大量帧),你的精灵移动得越快。为了解决这个问题,你必须考虑当前帧和前一帧之间经过的时间来移动你的精灵(你的电脑越慢,你的精灵在一帧中移动的越多,你的电脑越快,你的精灵在一帧中移动的越少)。 Timestep 将使您的精灵每秒移动 (x,y) 而不是每帧移动 (x,y),这正是您在大多数图形应用程序中所需要的。