基于时间的循环和基于帧的循环

Lew*_*rin 10 c++

试图理解在游戏循环中设置恒定速度的概念.我头疼.我阅读了deWiTTERS页面,但我看不出为什么/如何...当我得到它...它滑倒了.

while(true)
{
      player->update() ;
      player->draw() ;
}
Run Code Online (Sandbox Code Playgroud)

这将尽可能快地运行,具体取决于处理器的速度......我明白了.

要在所有计算机上以相同的速度运行,逻辑是我没有得到的.如果我试图以60fps运行,那么它意味着每16ms对象移动一帧,是吗?我没有得到的是如何update()draw()可能太慢.

deWiTTERS示例(我使用了60):

const int FRAMES_PER_SECOND = 60;
const int SKIP_TICKS = 1000 / FRAMES_PER_SECOND;

DWORD next_game_tick = GetTickCount();
// GetTickCount() returns the current number of milliseconds
// that have elapsed since the system was started

int sleep_time = 0;

bool game_is_running = true;

while( game_is_running ) {
    update_game();
    display_game();

    next_game_tick += SKIP_TICKS;
    sleep_time = next_game_tick - GetTickCount();
    if( sleep_time >= 0 ) {
        Sleep( sleep_time );
    }
    else {
        // Shit, we are running behind!
    }
}
Run Code Online (Sandbox Code Playgroud)

我不明白他为什么在循环开始之前获得当前时间.当他逐渐增加时SKIP_TICKS我理解他会增加到下一个16ms的间隔.但我也不明白这一部分:

sleep_time = nextgametick  - GetTickCount() 
Run Code Online (Sandbox Code Playgroud)

什么Sleep(sleep_time)意思?处理器离开循环并执行其他操作?它如何实现60fps的运行?

Bri*_*ron 5

如果update_game()和display_game()函数在比60FPs的单帧间隔更短的时间内完成,则循环尝试通过休眠(阻塞线程)来确保在该间隔启动之前不处理下一帧多余的帧时间.似乎它试图确保帧速率上限为60FPS,而不是更高.

处理器不会"离开循环",而是阻止运行循环的线程(阻止继续执行代码),直到睡眠时间结束.然后它继续到下一帧.在多线程游戏引擎中,像这样睡眠主游戏循环的线程使CPU有时间在其他线程中执行代码,这可能是管理物理,AI,音频混合等,具体取决于设置.

为什么在循环开始之前调用GetTickCount()?我们从代码中的注释中知道,GetTickCount()返回自系统引导以来的毫秒数.

因此,假设系统在您启动程序时已经运行了30秒(30,000ms),并且假设我们在进入循环之前没有调用GetTickCount(),而是将next_game_tick初始化为0.

我们进行更新和绘制调用(例如,它们需要6ms),然后:

next_game_tick += SKIP_TICKS;  // next_game_tick is now 16
sleep_time = next_game_tick - GetTickCount();   

// GetTickCount() returns 30000!
// So sleep_time is now 16 - 30000 = -29984 !!!
Run Code Online (Sandbox Code Playgroud)

因为我们(明智地)只在sleep_time为正时睡觉,所以游戏循环将尽可能快地运行(可能比60FPS快),这不是你想要的.