这是一个关于如何模拟和渲染视频游戏的示例(伪代码)。
//simulate 20ms into the future
const long delta = 20;
long simulationTime = 0;
while(true)
{
while(simulationTime < GetMilliSeconds()) //GetMilliSeconds = Wall Clock Time
{
//the frame we simulated is still in the past
input = GetUserlnput();
UpdateSimulation(delta, input);
//we are trying to catch up and eventually pass the wall clock time
simulationTime += delta;
}
//since my current simulation is in the future and
//my last simulation is in the past
//the current looking of the world has got to be somewhere inbetween
RenderGraphics(InterpolateWorldState(GetMilliSeconds() - simulationTime));
}
这是我的问题:
我有40ms通过外部'while true'循环(意味着25FPS)。 RenderGraphics方法需要10ms。这意味着内循环有30ms。 UpdateSimulation方法需要5ms。其他所有内容都可以忽略,因为它的值低于0.1ms。
为了保持40ms(外循环)的时间表,我可以设置变量'delta'的最大值是多少? 为什么?
答案 0 :(得分:0)
这在很大程度上取决于您想要和需要更新模拟状态和用户输入的频率,考虑到下面提到的限制。例如,如果您的游戏包含基于物理行为的内部状态,则需要较小的delta
以确保在游戏状态下正确评估并反映移动和碰撞(如果有)。此外,如果您的用户输入需要细粒度评估和状态更新,则还需要较小的delta
值。例如,具有模拟用户输入(例如鼠标,操纵杆)的射击游戏将受益于大于30Hz的更新频率。如果你的游戏不需要对输入和游戏状态进行如此高频率的评估,那么你可以获得更大的delta
值,或者甚至只要在检测到玩家的任何输入时更新你的游戏状态。 / p>
在您的特定伪代码中,您的模拟将根据长度为delta
的固定时间片进行更新,要求您在比挂钟时间更短的时钟时间内处理模拟更新模拟即可。否则,挂钟时间将比您的模拟时间更新更快。 这最终限制了您的delta
,具体取决于实际计算delta
模拟时间的模拟更新的速度。此关系还取决于您的使用情况,可能不是线性的或不变。例如,物理引擎通常会将内部给出的delta
时间划分为可以合理处理的更新速率,因为delta
次可能导致数值不稳定,并且更难以解决线性系统非线性地提高处理工作量。在其他用例中,模拟更新可能需要线性或甚至恒定的时间。即使这样,许多(可能是外部的)事件也可能导致模拟更新处理得太慢,如果它本身就要求很高的话。例如,在模拟更新期间加载资源,操作系统决定将执行线程放在一边,用户运行另一个进程,反病毒软件启动,内存压力低,CPU速度慢等等。到目前为止,我主要看到两种策略来规避这个问题或者解决它的影响。首先,如果模拟更新工作量很低并且假设减速原因只是暂时的,那么简单地忽略它就可以工作。这将导致模拟的或多或少明显的“慢动作”行为,这可能 - 在最坏的情况下 - 导致模拟时间延迟堆积永久。我经常看到的第二个策略是简单地将测量的帧时间限制为一些人工值,比如说1000ms。一旦减速原因消失,这将导致平稳行为,但缺点是“上限”模拟时间“丢失”,如果不处理或计算,可能导致动画打嗝。要选择策略,分析您的使用案例可能包括测量处理delta
和x * delta
时间模拟更新所需的挂钟时间,以及如何将delta
时间和模拟负载更改为流程实际上反映了计算它所需的挂钟时间,这将提示您{C}的最大值对于您的特定硬件和软件环境。