除了使用NSTimer之外,在iPhone上创建游戏循环的更好方法是什么?

时间:2008-09-18 19:55:35

标签: iphone objective-c cocoa

我在iPhone上编写游戏。我目前正在使用NSTimer来触发我的游戏更新/渲染。这个问题是(在分析之后)我似乎在更新/渲染之间失去了很多时间,这似乎主要与我插入NSTimer的时间间隔有关。

所以我的问题是使用NSTimer的最佳选择是什么?

请回答一个替代方案。

3 个答案:

答案 0 :(得分:18)

你可以通过线程获得更好的性能,尝试这样的事情:

- (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.在各种类型的游戏循环及其优缺点上有一个很棒的article。)

答案 1 :(得分:4)

我特别不了解iPhone,但我仍然可以提供帮助: 不要简单地在循环结束时插入固定的延迟,而是使用以下内容:

  • 确定您满意的刷新间隔,该间隔大于通过主循环的单次传递。
  • 在循环开始时,获取您可用的任何分辨率的当前时间戳并存储它。
  • 在循环结束时,取另一个时间戳,并确定自上一个时间戳以来经过的时间(在循环之前初始化)。
  • 睡眠/延迟理想帧时间与帧已经过的时间之间的差异。
  • 在下一帧,您甚至可以通过与上一个循环开始时的时间戳进行比较来尝试补偿睡眠间隔中的不准确性。存储差值并在此循环结束时从睡眠间隔中加/减它(睡眠/延迟可能太长或太短)。

您可能想要一个警报机制,让您知道您的时间是否过紧(即,如果您在所有补偿后的睡眠时间小于0,这意味着您需要更多时间处理比你的帧速率允许)。效果将是你的游戏速度减慢。对于额外的点,如果您发现这种情况,您可能希望暂时缩短渲染时间,直到您再次有足够的备用容量。

答案 2 :(得分:0)

使用CADisplayLink,您可以在XCODE中提供的OpenGL ES模板项目中找到(从这个模板开始创建项目并查看EAGLView类,此示例基于Open GL,但您可以使用CADisplayLink仅适用于其他类型的游戏