移动时略有停顿/延迟

Slight pause/delay when moving

本文关键字:延迟 移动      更新时间:2023-10-16

我今天一直在为我的游戏开发这个小框架,并意识到移动时会延迟。我以前使用过SFML,也遇到过同样的问题,但从未想过要解决它。我想知道是否有人遇到过类似的问题并找到了解决方案。

下面是一个让我在移动中稍微停顿的代码示例:

int main(){
    sf::RenderWindow window (sf::VideoMode(640, 480), "Window");
    //window.setVerticalSyncEnabled(true);
    sf::Texture tex;
    tex.loadFromFile("Assets/Textures/player.png");
    sf::Sprite s;
    s.setTexture(tex);
    while (window.isOpen()){
        sf::Event event;
        while (window.pollEvent(event)){
            if (event.type == sf::Event::Closed)
                window.close();
        }
        if (sf::Keyboard::isKeyPressed(sf::Keyboard::Right)){
            s.move(0.01f, 0.0f);
        }
        window.clear();
        window.draw(s);
        window.display();
    }
}

延迟/暂停/我所经历的一切都很轻微,但我能注意到,这真的让我很烦恼。仅仅是看到在没有任何值改变的情况下移动的轻微中断,我的编程头脑就非常难过。

键盘输入会有延迟,就像在Microsoft Word中按住键一样。为了解决这个问题,您可以创建一个变量,并在按键时将其设置为true。

int main(){
    sf::RenderWindow window (sf::VideoMode(640, 480), "Window");
    //window.setVerticalSyncEnabled(true);
    sf::Texture tex;
    tex.loadFromFile("Assets/Textures/player.png");
    sf::Sprite s;
    s.setTexture(tex);
    bool moving = false;
    while (window.isOpen()){
        sf::Event event;
        while (window.pollEvent(event)){
            if (event.type == sf::Event::Closed)
                window.close();
        }
        if (sf::Keyboard::isKeyPressed(sf::Keyboard::Right)){
            moving = true;
        }
        if (moving) {
            s.move(0.01f, 0.0f);
        }
        window.clear();
        window.draw(s);
        window.display();
    }
}

这听起来像是帧速率/定时问题。60hz游戏中的一帧是16.666.毫秒,但至少在Windows上,系统时钟的分辨率只有1ms,所以你的延迟将是16ms或17ms。这种不准确会导致偶尔的抖动,因为即使启用了vsync,一些帧也会被跳过(或者渲染两次,在您的情况下,会出现短暂的暂停)。

如果您可以手动控制帧定时,例如通过禁用sf::RenderWindow的帧速率限制并直接调用sf::sleep,一种解决方案是延迟序列中的每一帧:17、17、16、17、17和16,这样长期平均值接近60hz,从而最大限度地减少抖动。

我从未使用过SFML,所以我无法提供任何代码,但我希望这能为您指明正确的方向。

您还应该确保显示器的刷新率与游戏的帧速率相同。SFML可能已经在自动执行此操作。