使用循环在 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),这正是您在大多数图形应用程序中所需要的。