在游戏循环中使用sleep()会使delta时间不稳定

时间:2016-12-29 14:23:33

标签: c++ sfml game-loop

我正在用sfml编写一个游戏循环。当我没有睡眠时,每次循环迭代所用的时间约为1ms。但是当我添加睡眠(sleepTime)时突然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;
    }

不睡觉:https://aww.moe/sn1z0a.png

有了睡眠:https://aww.moe/7seof1.png

1 个答案:

答案 0 :(得分:3)

你正在尝试做什么 - 将游戏限制在特定的帧速率 - 已经内置到SFML中。只需使用您想要的帧速率作为参数调用var columnDefs = [ { name: 'Id' , field:'Id', editableCellTemplate:'<div class="input-group"> <input type="text" name="relatedpersonId" id="personidtxtboxdivision" ng-class="\'colt\' + col.index" ng-input="COL_FIELD" data-ng-model="row.entity.id" data-ng-keypress="grid.appScope.checkForValue()" data-ng-blur="grid.appScope.getData(row.entity)"/> <div class="input-group-btn postal-search" data-ng-disabled="true"> <button type="button" data-ng-click="grid.appScope.getData(row.entity)" class="btn btntable btn-xs icon-binoculars pull-right btn-default" title={{rs_select}}><i class="glyphicon glyphicon-search"></i></button></div></div>', }, { name: 'name' }, { name: 'gender' }, { name: 'salary' } ]; 即可进行设置。也可以使用垂直同步(通过使用sf::Window::setFrameRateLimit())来限制帧/更新的数量,虽然它通常被认为是一个坏主意,因为如果目标机器无法渲染,游戏也会变慢所需的帧速率(或高速运行在120或140Hz的高端屏幕)。

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

使用SFML的基本方法通常如下所示(这是来自内存,因此可能包含错误或拼写错误):

sf::Window::setVerticalSyncEnabled()

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(); } 的用法一开始可能不太清楚,但想象一下机器几乎无法每秒运行所需的100次更新的情况。如果你背后有20个更新(一些hick-up或其他什么),机器将永远无法再次正常赶上,导致严重的口吃或游戏无法响应。