为什么使用集成进行固定的时间步长游戏循环? (Gaffer on Games)

时间:2017-04-09 02:00:23

标签: c++ c game-engine game-loop

http://gafferongames.com/game-physics/fix-your-timestep/

http://www.koonsolo.com/news/dewitters-gameloop/

在Glenn Fiedler的 Fix Your Timestep!文章的最后一个游戏循环中,他使用了一个更新循环,将游戏逻辑推进了固定的增量时间。由于增量时间是固定的,为什么他会根据增量时间进行整合?在固定的基于时间步长的游戏中,移动不能像以下一样简单:

if ( keyboard pressing "W" ) {
    velocity += acceleration
}
position += velocity

而不是传递delta时间变量:

if ( keyboard pressing "W" ) {
    velocity += integrated(acceleration, delta_time)
}
position += velocity * delta_time

因为“固定”时间步长循环中的增量时间没有任何意义,所以就像将所有内容乘以1.在基于“变量”时间步长的游戏中,您必须使用增量时间并集成运动但在这种情况下它没关系。请注意delta时间的变量如何设置为常量且永不改变,游戏逻辑已经是确定性的,并且您似乎不需要在代码中的任何位置将delta速度和加速度乘以delta时间。我从文章中得到的是“修正你的时间步骤!”,顾名思义,所以你有确定性的游戏逻辑,而不是浮点不准确和爆炸物理变化的时间步长。我很困惑为什么delta时间被传递到更新函数,因为它似乎违背了本文的目的。事实上,这两篇文章都反对增量时间。

double t = 0.0;
double dt = 0.01;

double currentTime = hires_time_in_seconds();
double accumulator = 0.0;

State previous;
State current;

while ( !quit )
{
    double newTime = time();
    double frameTime = newTime - currentTime;
    if ( frameTime > 0.25 )
        frameTime = 0.25;
    currentTime = newTime;

    accumulator += frameTime;

    while ( accumulator >= dt )
    {
        previousState = currentState;
        integrate( currentState, t, dt ); // integration
        t += dt;
        accumulator -= dt;
    }

    const double alpha = accumulator / dt;

    State state = currentState * alpha + 
    previousState * ( 1.0 - alpha );

    render( state );
}

deWiTTERS最后一个游戏循环做同样的事情:固定时间步长,插值渲染,渲染跳过。但是它并没有提到像另一个那样的集成。

3 个答案:

答案 0 :(得分:2)

假设加速度随时间线性增加或减少,您可以将速度变化基于平均加速度

Δv = (a0 + a1)(Δt)/2

如果游戏中包含气动阻力等因素,那么加速度会受到速度^ 2的影响,通常使用Runge Kutta 4来更新每个时间步的速度变化和位置变化。

我的印象是,大多数基于PC的游戏对物理引擎使用独立的固定频率,理想情况下与帧速率无关。对于这些游戏,即使显示缓慢,如果玩家可以处理视觉效果,实际游戏也是相同的。我已经看到老式的赛车游戏能够做到这一点,图形性能不会影响物理效果,而较新的赛车游戏则会降低图形设置,从而提高游戏车的性能,这是一个错误。

链接到示例Windows代码,用于以几乎任何合理的固定频率运行线程,并且不随时间漂移。

16.66ms frames times. How do you get a perfect 60 fps when sleep() only goes by whole milliseconds?

在MSDOS时代,由于PC在(105/88)Mhz = 1.19318 Mhz运行计时器,因此游戏将其用作高精度计时器计数器。

答案 1 :(得分:1)

他这样做的原因是更复杂的方法是将物理模拟频率与渲染频率分离。这样,您可以以可变帧速率(120 FPS,60 FPS等)渲染,但仍以恒定速率更新游戏逻辑和物理。

这样做的好处之一是游戏逻辑无论FPS如何都会表现得相同(如果你在现代计算机上运行它们,很多旧游戏都会出现问题,因为它们的物理依赖于FPS)。另一个好处是,您可以使用集成逻辑在物理模拟步骤之间插入一些额外的帧,从而产生更流畅的动画。

答案 2 :(得分:0)

固定的时间步骤,实际上只应用于数学或科学应用。为什么?因为在游戏中,如果你以30fps的速度运行,那么你的delta时间大约为34ms,这意味着它需要34毫秒来更新前一帧并准备好更新下一帧。 。因此,在大多数应用程序中,固定的时间步骤无用。

当谈到物理引擎时,这几乎总是完全取决于你的游戏,但大多数时候,物理引擎在一个单独的线程上运行,但它仍然需要将增量时间作为参数来解决碰撞正确。

Delta时间是完成最后一帧所花费的时间。

我希望这会有所帮助。