NSTimer vs CACurrentMediaTime()

时间:2012-07-25 23:51:46

标签: ios nstimer game-engine

所以我正处于我的第一个iOS游戏中,并且正在努力寻找如何整合对象移动的最佳方法。

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

更具体地说,我不确定NSTimer类和CACurrentMediaTime()函数的功能。很难根据经验进行测试,因为我不确定哪个有更大的错误。例如,使用重复间隔为0.008(~2updates /屏幕刷新)的NSTimer并在连续调用时调用CACurrentMediaTime(),我发现调用之间的时间间隔在0.0075 - 0.009之间变化。很难说哪个是(小)不一致的原因。因此,我应该确定时间步骤:

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

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

  3. 学生和所有这一切的新手 - 请很好:)任何建议非常感谢。谢谢你的时间。

2 个答案:

答案 0 :(得分:38)

NSTimer不是实时计时器。它甚至不是很接近,也不是故意的。如果您正在查看超过半秒的任何事情,NSTimer是错误的工具。我甚至不推荐它用于不到一秒钟的事情。对于多秒钟的事情,特别是多分钟的事情,如果你真的不关心什么时候开火,那就太棒了。我一直都在使用它。

CACurrentMediaTime()不是计时器。它是系统中最准确的时间函数的包装器:mach_absolute_time()。因此,如果您真正关心现在的时间,并且您希望以人类可理解的数字,CACurrentMediaTime()是您的功能。 mach_absolute_time()将为您提供一个非常准确的数字,但它基于Mach absolute time unit,它实际上并不映射到人类认为的任何麻烦(并且每个CPU都有不同的比例)。这就是为什么我们CACurrentMediaTime()让我们的生活更轻松。

好的,所以NSTimer不是实时的,CACurrentMediaTime()不是计时器。什么是游戏程序员?

Grand Central Dispatch包含了我们所拥有的最好的“使这个时间运行”系统中的一个。这是一个调度源。我说“关于这个时间”,因为GCD仍然不像RTOS家伙那样真正“实时”。但对于游戏开发者来说,这是实时的。在Concurrency Programming Guide中查找创建计时器。还要看一下dispatch_after(),这对于一次性“在延迟后运行它”很有用。

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

您可能还想认真研究像cocos2d这样的系统,这是一个非常好的游戏引擎。它为您处理了很多这类细节,让您专注于游戏部分。

保持Apple框架,您还应该看看Core Animation。如果你用计时器在屏幕上移动东西,你不应该这样做。核心动画是你在屏幕上移动东西的方式。它可以为您提供更多细节,更快,使用的电量比您自己做的少得多,并且它将大量工作转移到GPU(如上所述)。它比UI游戏设计的要多一些,但它绝对可以用来构建简单的游戏。

当然还有GLKit,但那是完全不同的事情......

答案 1 :(得分:2)

根据NSTimer documentation the effective resolution of the time interval for a timer is limited to on the order of 50-100 milliseconds.,这可能是您看到时间间隔变化的原因。

我建议您将更新间隔更改为0.016秒,因为您的游戏状态没有理由比屏幕更频繁地更新。然后你可以使用CADisplayLink来处理时间。这应该非常准确,因为它使用显示刷新率。