我正在编写一款目前在
Windows和Mac OS X上运行的游戏.我的主游戏循环如下所示:
while(running) { ProcessOSMessages(); // Using Peek/Translate message in Win32 // and nextEventMatchingMask in Cocoa GameUpdate(); GameRender(); }
多数民众赞成显然有点简化,但这就是它的要点.在我可以完全控制应用程序的Windows中,它运行良好.不幸的是,Apple在Cocoa应用程序中有自己的做事方式.
当我第一次尝试在Cocoa中实现我的主循环时,我无法弄清楚在哪里放置它所以我每this post创建了我自己的NSApplication.我把我的GameFrame()放在我的run函数中,一切正常.
但是,我觉得这不是“正确”的做法.我想在Apple的生态系统中很好地发挥作用,而不是试图破解有效的解决方案.
来自apple的This article描述了使用NSTimer的旧方法,以及使用CVDisplayLink执行此操作的“新方法”.我已经连接了CVDisplayLink版本,但它感觉……很奇怪.我不喜欢我的游戏是由显示器驱动而不是相反的想法.
我唯一的两个选择是使用CVDisplayLink还是覆盖我自己的NSApplication?这些解决方案中没有一个感觉非常正确.
解决方法
我很想知道是否有人真正做过这件事需要权衡,但这是我的理解:
Apple推出了CVDisplayLink解决方案,而不是在使用-nextEventMatchingMask的主线程上进行循环:untilDate:inMode:dequeue:因为,我认为,它为UI控件提供了更好的响应能力.这可能与全屏游戏无关. (注意:您不需要替换NSApplication来使用这种形式的游戏循环.)我认为使用CVDisplayLink的主要潜在问题是它只会提前运行一帧并且它会提前做出这个决定,这甚至更强比垂直同步.从好的方面来说,它可能会改善延迟.
其他解决方案包括从游戏逻辑中解耦渲染并在主线程上定期运行游戏逻辑并在CVDisplayLink线程上渲染.但是,如果你遇到游戏驱动显示范式的问题,我可能只会推荐这个.