如何让 SFML 3.0 中的运动不那么不稳定?

问题描述 投票:0回答:1

我的 pong 实现非常不稳定,我认为这可能是因为我计算程序睡眠时间的方式。 最大帧速率设置为 60,我的计算机应该能够以 60 帧运行它。

我遵循了本指南,但我不确定我做得是否正确。

这是我的main.cpp文件:

#include <SFML/Graphics.hpp>
#include <iostream>

#include "Paddle.hpp"

int framerateLimit = 60; 
unsigned int width = 800;
unsigned int height = 600;

int main()
{
    sf::RenderWindow window(sf::VideoMode({width, height}), "My window");
    window.setFramerateLimit(framerateLimit);
    
    sf::RectangleShape leftPaddle;
    leftPaddle.setSize(sf::Vector2f(10,50));
    leftPaddle.setPosition(sf::Vector2f(20, height / 2.0 - leftPaddle.getSize().y/2));    
    std::cout << leftPaddle.getPosition().x << "," << leftPaddle.getPosition().y << std::endl;

    sf::RectangleShape rightPaddle;
    rightPaddle.setSize(sf::Vector2f(10, 50));
    rightPaddle.setPosition(sf::Vector2f(width - 20 - leftPaddle.getSize().x, height / 2.0 - leftPaddle.getSize().y / 2));

    sf::Clock clock;
    
    const float deltaTime = 0.01f;
    float accumulator = 0.0f;
    float currentTime = clock.getElapsedTime().asSeconds();
    

    while (window.isOpen())
    {
        
        int64_t startTicks = clock.getElapsedTime().asMilliseconds();

        float newTime = clock.getElapsedTime().asSeconds();
        float frameTime = newTime - currentTime;
        
        currentTime = newTime;

        accumulator += frameTime;
        

        while (accumulator >= deltaTime) {
            while (const std::optional event = window.pollEvent())
            {
                // "close requested" event: we close the window
                if (event->is<sf::Event::Closed>()) {
                    window.close();
                }
                if (sf::Keyboard::isKeyPressed(sf::Keyboard::Key::W)) {
                    Paddle::moveUp(leftPaddle);
                }
                if (sf::Keyboard::isKeyPressed(sf::Keyboard::Key::S)) {
                    Paddle::moveDown(leftPaddle);
                }
                if (sf::Keyboard::isKeyPressed(sf::Keyboard::Key::Up)) {
                    Paddle::moveUp(rightPaddle);
                }
                if (sf::Keyboard::isKeyPressed(sf::Keyboard::Key::Down)) {
                    Paddle::moveDown(rightPaddle);
                }

            }
            accumulator -= deltaTime;
        }

        const float alpha = accumulator / deltaTime;

        
        window.clear(sf::Color::Black);

        window.draw(leftPaddle);
        window.draw(rightPaddle);

        window.display();

        
        int frameTicks = clock.getElapsedTime().asMilliseconds() - startTicks;

        if (frameTicks < 1000 / framerateLimit) {
            int duration = 1000 / framerateLimit - frameTicks;
            sf::sleep(sf::milliseconds(duration));
        }
        
    }
}

这是我的运动实现:

#include "Paddle.hpp"

void Paddle::moveUp(sf::RectangleShape& paddle) {
    paddle.getPosition().y <= 10.f ? paddle.setPosition(sf::Vector2f(paddle.getPosition().x,0)) : paddle.move(sf::Vector2f(0, -10));
}

void Paddle::moveDown(sf::RectangleShape& paddle) {
    paddle.getPosition().y >= height - paddle.getSize().y - 10 ? paddle.setPosition(sf::Vector2f(paddle.getPosition().x,height - paddle.getSize().y)) : paddle.move(sf::Vector2f(0, 10));

}
c++ game-development sfml frame-rate
1个回答
0
投票

而不是使用 window.clear()、window.draw() 和 window.display() 然后睡觉。将这些调用放在 if() 语句中,该语句检查自上次重新绘制窗口以来是否已经过了 1/60 秒。

您还可以在绘制帧之前放置一些游戏计算逻辑,而不是您的 CPU 可以处理的数量

类似:

total += deltaTime;

if(total>=(1/framerate))
{
    total=0;
    additionalGameCalculationLogic();
    window.clear();
    window.draw();
    window.display();
}
© www.soinside.com 2019 - 2024. All rights reserved.