Какой лучший способ создать игровую петлю на iPhone, кроме использования NSTimer? - PullRequest
23 голосов
/ 18 сентября 2008

Я программирую игру на iPhone. В настоящее время я использую NSTimer для запуска обновления / рендеринга игры. Проблема с этим заключается в том, что (после профилирования) я теряю много времени между обновлениями / рендерингами, и это, по-видимому, в основном связано с интервалом времени, который я подключаю к NSTimer.

Итак, мой вопрос, какова лучшая альтернатива использованию NSTimer?

Один вариант за ответ, пожалуйста.

Ответы [ 3 ]

18 голосов
/ 22 октября 2008

Вы можете добиться лучшей производительности с потоками, попробуйте что-то вроде этого:

- (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. Есть большая статья о различных типах игровых циклов и их плюсах и минусах.)

4 голосов
/ 22 октября 2008

Я не знаю, в частности, об iPhone, но все же могу помочь: Вместо того, чтобы просто подключать фиксированную задержку в конце цикла, используйте следующее:

  • Определите интервал обновления, который вас устраивает, и он больше одного прохода через ваш основной цикл.
  • В начале цикла возьмите текущую временную метку любого имеющегося разрешения и сохраните ее.
  • В конце цикла возьмите другую временную метку и определите время, прошедшее с последней временной метки (инициализируйте его перед циклом).
  • сон / задержка для разницы между вашим идеальным временем кадра и уже прошедшим временем для кадра.
  • В следующем кадре вы даже можете попытаться компенсировать неточности в интервале ожидания путем сравнения с отметкой времени в начале предыдущего цикла. Сохраните разницу и добавьте / вычтите ее из интервала ожидания в конце этого цикла (режим сна / задержки может быть слишком длинным ИЛИ слишком коротким).

Возможно, вы захотите иметь механизм оповещения, который позволит вам знать, если у вас слишком мало времени (например, если ваше время сна после всех компенсаций меньше 0, что означает, что вы тратите больше времени) обрабатывать, чем позволяет ваша частота кадров). В результате ваша игра замедлится. Для получения дополнительных очков вы можете на некоторое время упростить рендеринг, если обнаружите, что это происходит, до тех пор, пока у вас снова не будет достаточно свободного места.

0 голосов
/ 29 ноября 2010

Используя CADisplayLink, вы можете найти, как в шаблоне проекта OpenGL ES, предоставленном в XCODE (создать проект, начиная с этого шаблона, и взглянуть на класс EAGLView, этот пример основан на открытом GL, но вы можете использовать CADisplayLink только для других видов игр

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...