除了使用NSTimer,还有什么比在iPhone上创建游戏循环更好的方法?
时间:2020-03-06 14:23:13 来源:igfitidea点击:
我正在用iPhone编写游戏。我目前正在使用NSTimer触发我的游戏更新/渲染。问题在于(在分析之后)我在更新/渲染之间似乎浪费了很多时间,这似乎与插入NSTimer的时间间隔有关。
所以我的问题是,使用NSTimer的最佳替代方法是什么?
请为每个答案一个选择。
解决方案
我不太了解iPhone,但我仍然可以提供帮助:
使用以下方法,而不是简单地在循环结束时插入固定的延迟:
- 确定我们希望使用的刷新间隔,该刷新间隔大于通过主循环的一次刷新间隔。
- 在循环开始时,获取可用分辨率的当前时间戳并将其存储。
- 在循环结束时,获取另一个时间戳,并确定自上一个时间戳以来经过的时间(在循环之前初始化此时间)。
- 睡眠/延迟,以获得理想帧时间与该帧已经经过的时间之间的差值。
- 在下一帧,我们甚至可以尝试通过与上一个循环开始时的时间戳进行比较来补偿睡眠间隔中的不准确性。存储差异并在此循环结束时从睡眠间隔中减去/减去(睡眠/延迟可能过长或者过短)。
我们可能希望有一个警报机制,让我们知道计时是否太紧(即,如果所有补偿后的睡眠时间都小于0,这意味着我们要花比帧频允许)。结果是游戏速度变慢。对于额外的点,如果检测到这种情况,可能要暂时简化渲染,直到再次有足够的备用容量。
我们可以通过线程获得更好的性能,请尝试如下操作:
- (void) gameLoop { while (running) { NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; [self renderFrame]; [pool release]; } } - (void) startLoop { running = YES; #ifdef THREADED_ANIMATION [NSThread detachNewThreadSelector:@selector(gameLoop) toTarget:self withObject:nil]; #else timer = [NSTimer scheduledTimerWithTimeInterval:1.0f/60 target:self selector:@selector(renderFrame) userInfo:nil repeats:YES]; #endif } - (void) stopLoop { [timer invalidate]; running = NO; }
在" renderFrame"方法中,我们准备帧缓冲区,绘制帧并将其显示在屏幕上。 (P.S.有一篇很棒的文章,介绍了各种类型的游戏循环及其优缺点。)
使用CADisplayLink,我们可以找到XCODE提供的OpenGL ES模板项目中的方式(从该模板开始创建一个项目,并查看EAGLView类,此示例基于开放式GL,但是我们只能将CADisplayLink用于其他种类的游戏