【问题标题】:NSTimer vs CACurrentMediaTime()NSTimer 与 CACurrentMediaTime()
【发布时间】:2012-07-24 12:21:03
【问题描述】:

因此,我正在开发我的第一个 iOS 游戏,并且正在努力寻找如何以最佳方式集成对象移动。

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

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

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

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

学生和所有这一切的新手 - 请善待 :) 非常感谢任何建议。感谢您的宝贵时间。

【问题讨论】:

    标签: ios nstimer game-engine


    【解决方案1】:

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

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

    【讨论】:

      【解决方案2】:

      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,但那是完全不同的东西......

      【讨论】:

      • 嗨,Rob,感谢您的出色回答!我非常感谢您抽出宝贵时间阅读并做出如此彻底的回应。谢谢!
      • 感谢您的详细回复!快速澄清:正如下面的一个答案所暗示的,NSTimer 文档声称effective resolution of the time interval for a timer is limited to on the order of 50-100 milliseconds. 您今天是否仍然建议避免使用 NSTimer 进行亚秒级任务?再次感谢!
      • 我仍然不会那么快地使用 NSTimers(当然不会使用选择器)。运行循环和调度开销似乎过多。可能我对它们过于谨慎,但 NSTimer 似乎是错误的工具。 (现在有一些基于块的接口可能是建立在 GCD 之上而不是运行循环之上的,所以这些可能完全没问题,但我没有对新接口进行太多探索。)
      猜你喜欢
      • 1970-01-01
      • 2016-06-19
      • 1970-01-01
      • 2015-10-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-07-15
      相关资源
      最近更新 更多