Я программирую игру на iPhone. В настоящее время я использую NSTimer для запуска обновления/рендеринга игры. Проблема в том, что (после профилирования) я теряю много времени между обновлениями/рендерингами, и это, похоже, связано с временным интервалом, который я ввожу в NSTimer.
Поэтому мой вопрос заключается в том, что является лучшей альтернативой использованию NSTimer?
Пожалуйста, по одной альтернативе на каждый ответ.
Вы можете получить лучшую производительность с помощью потоков, попробуйте сделать что-то вроде этого:
- (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. Есть отличная статья о различных типах игровых циклов и их плюсах и минусах).
Я не знаю конкретно про iPhone, но, возможно, смогу помочь: Вместо того чтобы просто подключать фиксированную задержку в конце цикла, используйте следующее:
Возможно, вы захотите иметь механизм оповещения, который даст вам знать, если вы слишком затягиваете время (т.е. если ваше время сна после всех компенсаций меньше 0, что означает, что вы тратите больше времени на обработку, чем позволяет ваша частота кадров). В результате ваша игра будет замедляться. Чтобы получить дополнительные очки, вы можете упростить рендеринг на некоторое время, если обнаружите, что это происходит, пока у вас снова не будет достаточно свободных мощностей.
Используйте CADisplayLink, вы можете найти как это сделать в проекте шаблона OpenGL ES, предоставленном в XCODE (создайте проект, начиная с этого шаблона и посмотрите на класс EAGLView, этот пример основан на open GL, но вы можете использовать CADisplayLink только для других видов игр).