Как сделать игровой цикл на iPhone без использования NSTimer - PullRequest
5 голосов
/ 29 августа 2009

Чтобы аккуратно перенести мою игру на iPhone, я пытаюсь создать игровой цикл, в котором не используется NSTimer.

В некотором примере кода я заметил, что, если использовать NSTimer, вы вначале настроили бы его на что-то вроде

    self.animationTimer = [NSTimer scheduledTimerWithTimeInterval:animationInterval target:self selector:@selector(drawView) userInfo:nil repeats:YES];

где drawView будет выглядеть примерно так:


- (void)drawView 
{
    glBindFramebufferOES(GL_FRAMEBUFFER_OES, viewFramebuffer);
    mFooModel->render();
    glBindRenderbufferOES(GL_RENDERBUFFER_OES, viewRenderbuffer);
    [context presentRenderbuffer:GL_RENDERBUFFER_OES];
}

При использовании этой техники mFooModel хорошо отрисовывается, но вместо этого я хочу создать свой собственный игровой цикл, который вызывает drawView вместо того, чтобы NSTimer вызывал drawView 60 раз в секунду. Я хотел бы что-то вроде:


while(gGameState != kShutDown)
{
    [self drawView]
}

К сожалению, когда я делаю это, все, что я получаю, это черный экран. Почему это происходит? Можно ли как-нибудь реализовать то, что я здесь описываю?

Причина, по которой я хочу избегать NSTimer, заключается в том, что я хочу делать обновления физики и ИИ в игровом цикле. Я использую свои собственные часы / таймер, чтобы отслеживать количество прошедшего времени, чтобы я мог сделать это точно. Рендеринг происходит максимально быстро. Я пытаюсь использовать некоторые методы, описанные в этой статье

Это довольно импульсивный вопрос (тот, который вы задаете после того, как весь день кодируете, застряли и надеетесь, что ответ придет к утру)

Ура, ребята.

Ответы [ 5 ]

21 голосов
/ 11 сентября 2009

Другой вариант с iPhoneOS 3.1 - использовать новый API CADisplayLink.Это вызовет селектор, который вы укажете, когда необходимо обновить содержимое экрана.

displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(renderAndUpdate)];
[displayLink setFrameInterval:2];
[displayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];

Новый шаблон проекта OpenGL в XCode также использует CADisplayLink, если вам нужен еще пример кода.

2 голосов
/ 16 февраля 2010

Будьте внимательны, используя self в качестве цели для displayLinkWithTarget, в руководстве написано: "Недавно созданная ссылка на дисплей сохраняет цель". Martin

2 голосов
/ 03 февраля 2010

Хотя CADisplayLink действительно хорошая альтернатива для игр на базе 3.1,
что-либо, использующее «Таймер» - действительно плохая идея.

Наилучшим подходом является старая добрая "тройная буферизация" для разделения работы графического процессора.

У Фабьена очень хорошее объяснение в обзоре Doom Iphone:
http://fabiensanglard.net/doomIphone/

2 голосов
/ 30 августа 2009

Если вы не хотите использовать NSTimer, вы можете попробовать запустить NSRunLoop вручную:

static BOOL shouldContinueGameLoop;
static void RunGameLoop() {
    NSRunLoop *currentRunLoop = [NSRunLoop currentRunLoop];
    NSDate *destDate = [[NSDate alloc] init];
    do {
        // Create an autorelease pool
        NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
        // Run the runloop to process OS events
        [currentRunLoop runUntilDate:destDate];
        // Your logic/draw code goes here
        // Drain the pool
        [pool drain];
        // Calculate the new date
        NSDate *newDate = [[NSDate alloc] initWithTimeInterval:1.0f/45 sinceDate:destDate];
        [destDate release];
        destDate = newDate;
    } while(shouldContinueGameLoop);
    [destDate release];
}
0 голосов
/ 10 февраля 2010

Что касается CADisplayLink и статьи о Doom для iPhone от Фабьена, я написал Фабьену по электронной почте и считаю, что лучший вариант - субъективен. В отношении производительности DisplayLink и тройная буферизация должны быть одинаковыми, но DisplayLink доступен только в> OS 3.1. Так что это должно быть вашим определяющим фактором.

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