这个问题专门针对具有物理和视觉组件(例如游戏)的反应性香蕉和实时模拟。
根据修复您的时间步长!设置游戏循环的理想方式(假设物理需要可重现),您需要帧之间的固定时间步长。在考虑了一些真正的复杂性之后,作者得出了这个游戏循环:
double t = 0.0;
const 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; // note: max frame time to avoid spiral of death
currentTime = newTime;
accumulator += frameTime;
while ( accumulator >= dt )
{
previousState = currentState;
integrate( currentState, t, dt );
t += dt;
accumulator -= dt;
}
const double alpha = accumulator / dt;
State state = currentState*alpha + previousState * ( 1.0 - alpha );
render( state );
}
概要是物理模拟总是以相同的时间增量 ( dt
) 为数值稳定性。安排这一点必须考虑到物理和视觉效果可能会以不同的频率更新,并且您不想落后太远。
例如,您可能希望以 20hz 的频率进行更新,但以 60hz 的帧速率进行视觉更新。该循环对物理场进行线性插值,以弥补物理场更新和图形更新之间的差异。
此外,当帧之间的时间差远大于dt
有一个循环来处理以dt
. 关于死亡螺旋的注释只是指您的物理计算根本无法跟上所需的更新频率的情况,因此您允许它跳过一些更新。
对于本次讨论,我最感兴趣的部分是安排对物理引擎的调用(对 的调用integrate
)总是由dt
. reactive-banana是否允许用户编写这种样式循环?如果有怎么办?也许一个做实时物理模拟的例子是有序的(或已经存在的)?