我的SFML / C ++程序按预期工作,但如何使运动变慢?

时间:2014-01-06 19:24:06

标签: c++ time clock sfml gravity

我制作了一个圆圈作为我们的玩家并设定了重力,但它工作得更快,我甚至看不到。我认为它必须用sf :: time或sf :: clock做一些事情但是怎么做?我实际上没有得到这两个,所以任何代码示例和解释将不胜感激。这是我的代码: -

#include <SFML/Graphics.hpp>

int main()
{
    sf::RenderWindow window(sf::VideoMode(800, 600), "SFML works!");
    sf::CircleShape shape(20);
    shape.setFillColor(sf::Color::White);
    shape.setPosition(380, 550);
    shape.setOutlineColor(sf::Color::Green);
    shape.setOutlineThickness(3);

    while (window.isOpen())
    {
        sf::Event event;
        while (window.pollEvent(event))
        {
            if (event.type == sf::Event::Closed)
                window.close();
            if(sf::Keyboard::isKeyPressed(sf::Keyboard::Up))
                {
                    shape.move(0, -100);
                }
                if(event.KeyReleased)
                {
                    if(event.key.code == sf::Keyboard::Up)
                    {
                    int x[] = { 10, 10, 10, 10, 10};
                    for (int y = 0; y <= 4; y++)
                    {
                        shape.move(0, x[y]);
                    }

                    }
                }

        }

        window.clear(sf::Color::Black);
        window.draw(shape);
        window.display();
    }

    return 0;
}

2 个答案:

答案 0 :(得分:8)

请记住,你的程序可能每秒运行数百帧,所以当你按下键盘上的向上按钮时,每帧移动对象-100像素,这绝对不是你想要的。

那你怎么解决这个问题呢?你需要包括时间概念。我们通过使用时间步骤来查看自上一帧被调用以来已经过去多少时间。

这是一个简短的示例代码,显示了如何构建这个时间步骤(每种方法都有许多不同的优点和缺点)。

sf::Time timePerFrame = sf::seconds(1.0f / 60.0f); // 60 frames per second
sf::Clock deltaClock;  // This will track how much time has past since the last frame
sf::Time timeSinceLastUpdate = sf::Time::Zero;

while (m_Window.isOpen())
{
    sf::Time deltaTime = deltaClock.restart();  // Restart returns the time since the last restart call
    timeSinceLastUpdate += deltaTime;

    while (timeSinceLastUpdate >= timePerFrame)
    {
        timeSinceLastUpdate -= timePerFrame;

        ProcessInput();
        Update(timePerFrame);  // Notice how I pass the time per frame to the update function
    }

    Render();
}

然后在您的更新代码中,您只需将您想要移动的距离乘以您传递给更新函数的对象timePerFrame(确保使用sf::Time::asSeconds())。例如,您的代码看起来像这样

shape.move(0, -100 * timePerFrame.asSeconds());

如果您正在寻找有关时间步骤如何运作的深入解释,我会推荐这篇文章http://gafferongames.com/game-physics/fix-your-timestep/

答案 1 :(得分:1)

正如@Zereo做出回应但是有一个简单的版本:你可以让SFML照顾你,而不是照顾帧率:

    window.setFramerateLimit(60);

创建窗口后放置此行,SFML会将帧限制在60 / s。