NSTimer vs CACurrentMediaTime()

所以我在我的第一个iOS游戏中,正在努力如何去整合对象移动的最佳方式。

游戏很大程度上依赖于快速移动的对象和不断快速的用户input变化。 因此,我试图尽可能快速和准确地运行对象集成和约束求解器(以最小化在连续的游戏循环调用之间的用户input变化)。

更具体地说,我不确定NSTimer类和CACurrentMediaTime()函数的function。 因为我不确定哪个有较大的错误,所以很难进行经验性的检验。 例如,使用重复间隔为0.008(~2更新/屏幕刷新)的NSTimer,并在连续调用时调用CACurrentMediaTime(),我发现调用之间的时间间隔从0.0075 – 0.009。 很难说哪个是(小)不一致的原因。 所以为了确定时间步骤应该是:

  1. 假设NSTimer足够精确,可以使用NSTimer时间间隔作为游戏循环时间步长

  2. 使用CACurrentMediaTime()来确定连续的游戏循环调用之间的时间间隔。

学生和新的所有这一切 – 请成为好:)任何意见是非常感谢。 谢谢你的时间。

NSTimer不是一个实时计时器。 这并不是接近,也不是这个意思。 如果你正在看什么比大约半秒快, NSTimer是错误的工具。 我甚至不会推荐它在一秒钟之内的事情。 对于多秒钟的事情,尤其是多分钟的事情,当你真的不在乎什么时候发生的事情,这是很好的。 我用它所有的时间。

CACurrentMediaTime()不是一个计时器。 它是系统中最准确的时间函数的包装: mach_absolute_time() 。 所以如果你真的在乎现在是什么时候,那么你可以用一个人们可以理解的数字, CACurrentMediaTime()是你的function。 mach_absolute_time()会给你一个非常准确的数字,但它是基于马赫绝对时间单位 ,它实际上并不映射任何讨厌的人认为(和每个CPU有不同的规模)。 这就是为什么我们有CACurrentMediaTime()来让我们的生活更轻松。

好的,所以NSTimer不是实时的,并且CACurrentMediaTime()不是一个定时器。 什么是游戏程序员要做的?

大中央调度包括一些最好的“使这个运行在这个时候”系统我们有。 这是一个调度来源。 我说“关于这个时间”,因为GCD还没有像RTOS家伙那样真正的“实时”。 但对于游戏开发者来说,这是足够实时的。 在“ 并发编程指南”中查找创build定时器。 另外请看dispatch_after() ,这对于一次性运行是有好处的“延迟后运行”。

请记住,在主线程(UI线程,所有绘图完成的地方)上运行的任何内容都将与该线程上的所有其他内容共享时间。 所以你经常需要在后台线程上进行计算,而在主线程上处理绘图和用户交互。 这是GCD dispatch_queues旨在帮助你的那种东西。 另一方面,请记住,许多iOS设备是单核的。 所以“后台线程”有点用词不当。 一次只能有一件事情在CPU上运行。 这就是为什么把东西移到GPU上如此重要(见下文)。

你也可能想认真看看像cocos2d这样的系统,这是一个非常好的游戏引擎。 它为您处理了许多这些细节,让您专注于游戏部分。

留在苹果的框架,你也应该看看核心animation。 如果你用计时器在屏幕上移动,你不应该这样做。 核心animation是你如何在屏幕上移动的东西。 它为您处理了许多细节,速度更快,使用的电池less得多,而且将大量工作转移到GPU上(如上所述)。 这是一个比游戏UI元素更多的devise,但它绝对可以用来build立简单的游戏。

当然还有GLKit,但这是一个完全不同的东西….

根据NSTimer文档 the effective resolution of the time interval for a timer is limited to on the order of 50-100 milliseconds. 这可能是为什么你看到时间间隔的变化。

我build议的做法是将更新间隔更改为0.016秒,因为没有任何理由让您的游戏状态更新频率超过屏幕可以绘制的时间。 然后您可以使用CADisplayLink来处理时间。 这应该是非常准确的,因为它使用显示刷新率。