XNA如何保持一致且精确的60 FPS帧速率?另外,如何在不将CPU固定在100%的情况下保持如此精确的时序?
答案 0 :(得分:4)
虽然上面的luke代码是理论上正确的,但使用的方法和属性并不是最好的选择:
DateTime.Now
的精度仅为约30ms(参见C# DateTime.Now precision并给出或需要20ms),因此不建议使用高性能时序(60 FPS为16ms)。 System.Diagnostics.Stopwatch是the timer of choice for real time .NET Thread.Sleep
遇到相同的精度/分辨率问题,并且无法保证仅在指定时间内休眠当前的XNA FX似乎挂钩到Windows消息循环并执行其内部预更新的每一步并仅在自上次更新以来经过的时间与指定的帧速率匹配时调用Game.Update
(例如,每个16ms为默认设置)。如果您想真正了解XNA FX如何完成工作Reflector是您的朋友:)
随机花絮:回到XNA GameStudio 1.0 Alpha / Beta时间框架,有很多关于“完美的WinForms游戏循环”的博客文章,虽然我现在找不到它们......
答案 1 :(得分:2)
我不知道XNA是如何做到的,但几年前在使用OpenGL时,我使用一些非常简单的代码完成了同样的事情。
在它的核心我假设XNA有某种渲染循环,它可能会或可能不会与标准的偶数处理循环集成,但为了举例,我们假设它不是。在这种情况下,你可以写一些这样的东西。
TimeSpan FrameInterval = TimeSpan.FromMillis(1000.0/60.0);
DateTime PrevFrameTime = DateTime.MinValue;
while(true)
{
DateTime CurrentFrameTime = DateTime.Now;
TimeSpan diff = DateTime.Now - PrevFrameTime;
if(diff < FrameInterval)
{
DrawScene();
PrevFrameTime = CurrentFrameTime;
}
else
{
Thread.Sleep(FrameInterval - diff);
}
}
实际上你可能会使用像Environment.Ticks这样的东西而不是DateTimes(它会更准确),但我认为这说明了这一点。这应该只调用drawScene大约每秒60次,其余时间线程将处于休眠状态,因此不会产生任何CPU时间。
答案 2 :(得分:0)
游戏应该以60fps的速度运行,但这并不意味着他们会这样做。这实际上是已发布游戏的上限。
如果您在调试模式下运行游戏,您每秒可以获得更高的帧数 - 例如,我的笔记本电脑上的空白启动器模板在调试模式下的运行速度超过1,000fps。
据说发布的游戏中的XNA框架将尽力以60fps运行 - 但是您在项目中包含的代码有可能降低该性能。例如,有一些东西不断点燃垃圾收集,你通常会看到游戏的fps下降,或者在更新或绘制方法中抛出一些复杂的数学 - 因此让它们每一帧都开火......这通常会有点过分。为了让您的游戏尽可能精简,有许多事情要记住。
如果你问的是XNA框架如何实现这个天花板 - 我无法解释 - 但我可以说,这取决于你如何布局代码 - 你可以做什么肯定会对这个数字产生负面影响,而且它不会始终必须与CPU相关。在垃圾收集的例子中,它只是清理一个RAM,它可能根本不显示CPU使用率的峰值 - 但可能会影响你的FPS,具体取决于垃圾量和它必须运行的间隔。
答案 3 :(得分:0)
你可以在这里阅读关于如何在这里实现XNA定时器的所有内容Game timing in XNA Game Studio,但基本上它会在再次继续循环之前尝试1/60秒,同时请注意在更新之前可以多次调用更新如果XNA需要“追赶”,则渲染。