所以我正在将这款智能手机应用程序模拟到Windows.这是一个运行它的逻辑和绘制方法的游戏1/60.这是毫秒16.6667
我实现了这个游戏循环:
private const double UPDATE_RATE = 1000d / 60d;
private void GameLoop()
{
double startTime;
while (GetStatus() != GameStatus.NotConnected)
{
startTime = Program.TimeInMillis;
//Update Logic
while (Program.TimeInMillis - startTime <= UPDATE_RATE)
{
//Thread.Yield(); it consumed CPU before adding this too, adding this had no effect
Thread.Sleep(TimeSpan.FromTicks(1));//don't eat my cpu
}
}
Debug.WriteLine("GameLoop shutdown");
}
Run Code Online (Sandbox Code Playgroud)
Program.TimeInMillis来自一个NanoStopwatch班级,以毫秒为单位返回时间double.这很有用,因为这个游戏循环必须非常准确才能使一切正常.
你可能知道,这里Thread.Sleep会耗费大量的CPU.可能是因为它需要int millis将我转换TimeSpan为0毫秒.
我最近遇到了这个叫做的东西WaitHandle,但我看到的一切都用了int millis.我真的需要让这个准确,所以我真的需要double millis或microseconds/nanoseconds.
C#中有什么东西允许我Wait使用x微秒.我不介意自己创造一些东西(就像我为此做的那样NanoStopwatch),但我需要指出正确的方向.在互联网上找到了很多,但一切都用,而且int millis对我来说不够准确.
我运行了一些测试,改变Sleep使用类似的东西:UPDATE_RATE - (Program.TimeInMillis - startTime)这不是让我的游戏循环准确.
我希望一切都足够清楚,如果您需要更多信息,请发表评论.
文艺青年最爱的-有没有什么办法让一个线程等待量microseconds/nanoseconds的C#?我的游戏循环需要准确,毫秒对我来说不够准确.
提前致谢!
Han*_*ant 10
您需要硬件支持才能达到此类准确性.产生中断和触发代码以完成工作的信号.在Windows中,有两个明显的候选者可以使用这样的信号.
第一个是VSYNC中断,一个视频设备驱动程序实现细节.它出现在显示器刷新率下,液晶显示器通常为60赫兹.正是你要求的当然,不是巧合.大多数程序员使用DirectX来实现游戏图形,你要求它使用D3DPRESENT设置的信号.否则很不清楚你为什么不在问题中使用它,而是你应该追求的解决方案.
第二个是时钟中断.这就是你抱怨的那个.在Windows上是一个大问题,这是唤醒线程调度程序并获取代码运行的信号.它直接负责Thread.Sleep()的准确性.在发生时钟中断并且调度程序将线程重新置于活动状态之前,休眠的代码无法再次开始运行.没有其他办法可以做到这一点,处理器在物理上通过HLT指令关闭,不消耗功率,只能通过中断唤醒.默认情况下,时钟中断每秒触发64次.每15.625毫秒一次.它往往会被司机和其他东西修补,他们经常将它重新编程为10毫秒.提供免费软件并持有股份的公司使自己的产品看起来很好,使其低至1毫秒.
如果由于某种原因无法驯服DirectX,那么您还需要做什么.Pinvoke timeBeginPeriod(1)获得1毫秒的精度.从技术上讲,你可以使用NtSetTimerResolution()来低至500微秒,但这是一个低的表盘.并且请记住,您无法始终如一地维持此类速率,线程调度量,垃圾收集暂停,硬分页错误以及以实时优先级运行其代码的令人讨厌的设备驱动程序需要更长时间.
| 归档时间: |
|
| 查看次数: |
781 次 |
| 最近记录: |