如何在新旧iPhone上获得一致的速度?

如何在新旧iPhone上获得一致的速度?,iphone,frame-rate,game-loop,Iphone,Frame Rate,Game Loop,我正在用OpenGL ES为iPhone创建一个2D游戏。我正在使用NSTimer以0.002(60 fps)的间隔调用我的游戏循环,重复次数设置为“否”(我正在按照建议从函数中再次运行NSTimer): 这在我的3GS上运行平稳,但当我在2G上测试时,游戏运行速度要慢得多,有时我会偶尔出现空白帧。当我将间隔降低到0.033(30 fps)时。3G的速度太慢了 我知道一定有办法在两台设备上都能播放。Doodle Jump在两款手机上运行平稳,帧速率相同。关键问题在于: 您的游戏需要根据自上次渲染

我正在用OpenGL ES为iPhone创建一个2D游戏。我正在使用NSTimer以0.002(60 fps)的间隔调用我的游戏循环,重复次数设置为“否”(我正在按照建议从函数中再次运行NSTimer):

这在我的3GS上运行平稳,但当我在2G上测试时,游戏运行速度要慢得多,有时我会偶尔出现空白帧。当我将间隔降低到0.033(30 fps)时。3G的速度太慢了


我知道一定有办法在两台设备上都能播放。Doodle Jump在两款手机上运行平稳,帧速率相同。

关键问题在于:

您的游戏需要根据自上次渲染以来经过的时间量进行更新,而不是根据渲染的次数进行更新。假设您正在根据某个速度计算精灵的位置。新位置应基于渲染之间的时间进行计算,而不是假设自上次渲染以来已过0.002秒。这称为FPS独立动画

下面是一个简单的例子:

// FPS dependent animation
int x = sprite.x + sprite.velocity.x
正确的方法是使用自上次渲染以来的时间,并按比例进行更新。以下代码假定0.002为时基

// FPS independent animation
int x = sprite.x + sprite.velocity.x * time_since_last_render/0.002
在渲染需要两倍时间的设备上,下一次更新会将对象移动两倍的距离,因此它最终会在速度更快的设备上移动到相同的位置


另一个问题是,您不应该总是在未来0.002秒渲染下一帧。您应该看到当前帧渲染所用的时间,从0.002中减去该时间,然后使用该时间安排下一次渲染。当然,这个数字的最小值为零,所以在速度较慢的设备上,您不会开始将时间安排到过去。例如,如果渲染功能只需0.002秒即可渲染,这将不必要地将帧速率降低一半。

实际上有两种帧速率:

  • 显示帧速率:屏幕重画的速率
  • 逻辑帧速率:游戏逻辑更新的速率(游戏速度)
我认为您正在寻找一个恒定的逻辑帧速率,它与根据手机硬件功能调整的显示帧速率分离。与必须为每个逻辑帧完成一个显示帧的游戏循环进行比较


查看游戏逻辑中描述的“恒定游戏速度和最大FPS”算法,3G和2GS上的运行速度似乎相同,但显示帧速率将调整为较慢的2G CPU。虽然上面的文章没有介绍,但您也可以限制显示帧速率以节省电池。

好吧,关于何时放弃硬件架构,还有一个肮脏的想法。从iOS4开始,苹果(正式)放弃了对iPhone2G(原版iPhone)的支持。也许,也许你可以考虑做同样的事情,因为任何未来的OpenGL ES更新只针对3GS和以上(看看苹果现在如何运载OpenGL ES2设备能力的系统-即使3G不是ES2能力)。不是告诉你你有一个很糟糕的问题,(实际上,我有1)它只是说,有时你需要考虑你的应用程序的未来。我肯定会不理会Prime3GS设备(我不知道任何有2G的人了)。但同时,我想我真的应该把游戏速度和帧速率分开。无论如何,OpenGLES2将是我的下一个努力!谢谢我会通过简单地获得当前时间减去上一帧时间的差来计算自上次渲染以来的时间吗?
// FPS independent animation
int x = sprite.x + sprite.velocity.x * time_since_last_render/0.002