C++ 在游戏循环中使用sleep()会使增量时间不稳定

C++ 在游戏循环中使用sleep()会使增量时间不稳定,c++,sfml,game-loop,C++,Sfml,Game Loop,我正在用sfml编写一个游戏循环。当我不让它休眠时,每次循环迭代所用的时间约为1ms。但当我加上睡眠(睡眠时间)时,dt突然升高。我在循环开始时重新启动dt,但它似乎增加了最后的睡眠时间。是什么原因造成的 sf::Clock clock; float dt; sf::Time sleepTime = sf::milliseconds(0); while(m_Window.isOpen()) { sf::Time elapsed = clock.restart(); dt = e

我正在用sfml编写一个游戏循环。当我不让它休眠时,每次循环迭代所用的时间约为1ms。但当我加上睡眠(睡眠时间)时,dt突然升高。我在循环开始时重新启动dt,但它似乎增加了最后的睡眠时间。是什么原因造成的

sf::Clock clock;
float dt;
sf::Time sleepTime = sf::milliseconds(0);

while(m_Window.isOpen())
{
    sf::Time elapsed = clock.restart();
    dt = elapsed.asMilliseconds();

    cout << "Elapsed: " << dt;

    sf::Event event;

    while(m_Window.pollEvent(event))
    {
        switch(event.type)
        {
            case sf::Event::Closed:
                m_Window.close();
                break;
        }
    }

    sleepTime = sf::milliseconds(16 - dt);

    float time = sleepTime.asMilliseconds();
    cout << "\tSleep time: " << time << endl;

    if(sleepTime >= sf::Time::Zero)
    {
        sf::sleep(sleepTime);
    }
    else
    {
        cout << "Shit." << endl;
    }
sf::时钟;
浮动dt;
sf::Time sleepTime=sf::毫秒(0);
while(m_Window.isOpen())
{
sf::经过的时间=clock.restart();
dt=经过的时间。asmillseconds();

SFML中已经内置了您试图执行的操作–将游戏限制在特定的帧速率内。只需使用您想要的帧速率作为参数调用
sf::Window::setFrameRateLimit()
,您就可以进行设置。还可以使用垂直同步(通过使用
sf::Window::setVerticalSyncEnabled()
)限制帧数/更新,尽管这通常被认为是一个坏主意,因为如果目标机器不能以所需的帧率渲染(或在120或140Hz的高端屏幕上加速),游戏也会变慢

但是,您通常希望断开游戏更新与帧速率的连接,这样即使当前机器无法足够快地更新屏幕,游戏也不会减速

使用SFML的基本方法通常如下所示(这是从内存中获取的,因此可能包括bug或打字错误):

sf::Clock UpdateTime;//用于监视所经过时间的时钟
sf::Time passedTime;//累计游戏时间
const sf::Time frameTime(sf::毫秒(10));//每帧的预期时间;此处:10ms
while(window.isOpen()){
sf::事件;
while(window.pollEvent(事件)){
//事件处理
}
//首先加上经过的时间
passedTime+=UpdateLock.restart();
unsigned int numUpdates=0;//计算完成的更新
//只要经过足够的时间,就进行更新
//达到特定的最大值以避免出现问题,例如。
//主线程被阻塞或无法跟上
while(passedTime>=帧时间){
if(numUpdates++<10){
//在这里更新你的游戏吗
}
//减去我们“处理”的时间
passedTime-=帧时间;
}
window.clear();
//在这里画你的游戏
window.display();
}

numUpdates
的用法一开始可能不太清楚,但想象一下,在这种情况下,机器每秒几乎无法运行所需的100次更新。如果您落后20次更新(一些故障或其他情况)机器将永远无法正常追赶,导致严重口吃或游戏变得无反应。

睡眠导致它。你为什么要睡觉?因为我想建立恒定的游戏速度。我使用:作为向导。我知道睡眠()不是非常精确。但我在循环开始时重新启动dt,为什么要将睡眠时间添加到dt中?睡眠不会建立任何类似于恒定游戏速度的东西。这就是分时操作系统的本质。我不清楚-你期望什么样的输出?你每次迭代都要轮询一次时钟,其中包括睡眠。为什么睡眠时间不应该包括在这个读数中吗?也许你的意思是在计算
睡眠时间之前再次轮询时钟?@Glamhoth不要第二次重新启动计时器(在最后)。否则你就失去了绘制所有内容所花费的时间。
sf::Clock updateTimer; // Clock to monitor the time passed
sf::Time passedTime; // Accumulated game time
const sf::Time frameTime(sf::milliseconds(10)); // intended time per frame; here: 10ms

while (window.isOpen()) {
    sf::Event event;
    while (window.pollEvent(event)) {
        // Event handling
    }

    // First add the time passed
    passedTime += updateClock.restart();

    unsigned int numUpdates = 0; // Count the updates done

    // As long as enough time passed, do an update
    // Up to a specific maximum to avoid problems, e.g.
    // the main thread was blocked or can't catch up
    while (passedTime >= frameTime) {

        if (numUpdates++ < 10) {
            // Do your game update here
        }

        // Subtract the time we've "handled"
        passedTime -= frameTime;
    }

    window.clear();
    // Draw your game here
    window.display();
}