我有一个游戏引擎可以作为课程的一部分工作。目前,其渲染速度取决于帧速率,并且一个要求是转向基于计时器的依赖项。我不知道如何确定它依赖于帧速率。我不知道该找什么。我意识到我将需要以某种方式合并一个计时器(GetTickCount?)来完成此任务,但我不确定更新频率有多频繁。使程序基于定时器而不是帧速率相关?
我不想交代码,只是一些有用的指导方针吗?
我有一个游戏引擎可以作为课程的一部分工作。目前,其渲染速度取决于帧速率,并且一个要求是转向基于计时器的依赖项。我不知道如何确定它依赖于帧速率。我不知道该找什么。我意识到我将需要以某种方式合并一个计时器(GetTickCount?)来完成此任务,但我不确定更新频率有多频繁。使程序基于定时器而不是帧速率相关?
我不想交代码,只是一些有用的指导方针吗?
我以前fix your timestep一些成功
然后问题就变成了保留任何滞后的轨道......和拖慢的事情,如果计算机无法跟上。
一个可能的伪游戏循环:
constant TIMETHRESHOLD xxxx // nanoseconds to pass between executions of game loop
while true loop
if getTime() - previousTime > TIMETHRESHOLD
previousTime = getTime();
// Execute game logic here
end if
end loop
的事情是,你可以有游戏逻辑的不同部位不同TIMETHRESHOLD。例如,您可能希望帧速率为60fps,但如果物理引擎以30fps“工作”就足够了......这种类型的东西。如果硬件速度很快,它可以按照预期工作,而硬件速度较慢(不能满足时间要求的硬件),它的速度将会尽可能快。当然,这是一个简单的单进程示例。
想象一下,你有一个非常简单的游戏,它只是一个穿过屏幕的球。没有基于时间的更新,它会随着更新而移动。
你想要做的是找出多少时间已经过去当更新的,而不是像这样,(在一小部分,我通常衡量秒,所以物理方程匹配更好。):
ballPosition += ballVelocity
你必须这样:
ballPosition += ballVelocity * timeElapsed
这意味着,对于更高的帧速率,timeElapsed
会更低,因此其移动球少。较低的帧速率意味着timeElapsed
会更大,并且球会每帧移动更多。
最后,球会移动相同的距离,而不受帧频的影响。 60 FPS更新率使得timeElapsed
等于0.01666667f
,而30 FPS更新率将使其0.03333333f
。您可以看到60 FPS时的流逝时间是30 FPS的一半,但由于速度是原来的两倍,所以它是相同的数字。
我通常会将timeElapsed
作为参数传递给任何时间依赖的函数。这样做的一个很好的结果是,你可以通过将经过时间乘以一个值来减慢或加速你的游戏。您也可以将其应用于单个组件。如果您切换到限制帧的模型,它也会起到很好的作用,因为您只是强制timeElapsed
成为常量。伪代码:
while (gameRunning)
{
const float timeElapsed =
timer.elapsed(); // elapsed returns the number of seconds
// passed since it was last called
// GlobalTimeScale is 1 for normal time
game.update(timeElapsed * GlobalTimeScale);
game.draw();
}
要获取时间,GetTickCount
应该工作。您也可以查看QueryPerformanceCounter
以获得更高的精度,但它可能在多个内核方面存在问题。
该方案的问题是,您正在设置基于前一帧的速度下一帧的时间。通常这会引起一个令人讨厌的口吃效果,因为驱动程序缓冲了多个数据帧。如果你打算这样做,最好是平均数帧。这将消除很多这些口吃问题。 – Goz 2009-11-17 09:06:01
@Goz:你说的是某种浮动平均0.50 *上涨+0.30 *之前+ 0.20前beforeBeforeLast?即给予近期更多的权重以更快适应变化。 – 2009-11-17 13:04:56
你可以加权。就我个人而言,我发现即使在帧速率非常低(15fps)的情况下,平均最后3帧速率也会给您带来足够好的效果,从而不会显眼:) – Goz 2009-11-17 14:55:16
如果您不确定帧频的使用位置,它几乎肯定隐含在您的主循环中。如果您在主循环中调用渲染函数,并且渲染需要很长时间,那么主循环的“循环速率”与帧速率相同,对吧?单线程执行意味着在循环中处理的所有内容都有助于提高帧速率。
那么,你受限于你的帧率,不是吗?例如,如果帧速率滞后,则不能连续更新输入。 – 2009-11-16 18:35:30
这是一个合乎逻辑的假设。然而,就目前而言,它非常停顿,随着计算机的速度波动。我假设我被要求保持这种稳定的基于计时器的状态,而不是只是随机更新和渲染?我真的不完全理解,因此这个问题:) – Mark 2009-11-16 18:37:47