¿Cuál es la mejor manera de crear un bucle de juego en el iPhone que no sea el uso de NSTimer?

Estoy programando un juego en el iPhone. Actualmente estoy usando NSTimer para activar mi actualización/procesamiento del juego. El problema con esto es que (después del perfilado) parece que pierdo mucho tiempo entre actualizaciones/renders y esto parece tener que ver principalmente con el intervalo de tiempo que conecto a NSTimer.

Entonces mi pregunta es ¿cuál es la mejor alternativa para usar NSTimer?

Una alternativa por respuesta, por favor.

0
agregado editado
Puntos de vista: 3
He visto muchos ejemplos e investigado alternativas en internet. Entonces ya sé que hay algunas alternativas. Lo que realmente busco es lo que otras personas piensan que es la mejor alternativa. Estoy trabajando en un proyecto extremadamente corto, por lo que cualquier tiempo ahorrado en la investigación será de gran ayuda.
agregado el autor Ashley Davis, fuente
¿Has mirado los ejemplos de desarrollador de iPhone? Creo que hay algunos ejemplos (Touch Fighter o CrashLanding, por ejemplo) que pueden ser esclarecedores.
agregado el autor Mark Bessey, fuente

3 Respuestas

Puede obtener un mejor rendimiento con hilos, pruebe algo como esto:

- (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;
}

En el método renderFrame Usted prepara el framebuffer, dibuja el cuadro y presenta el framebuffer en la pantalla. (P.S. Hay un gran artículo sobre varios tipos de bucles de juego y sus pros y sus contras).

0
agregado
@zoul: ¿la alternativa THREADED_ANIMATION también funciona para versiones anteriores? Pensé que lo leí, no en algún lado.
agregado el autor Jonas Byström, fuente
@tc: Tiene razón, pero el cartel no dice nada sobre la capa de gráficos que usa. Ya que estamos hablando de juegos, asumí OpenGL, donde dicho circuito funciona sin problemas.
agregado el autor zoul, fuente
¿Te refieres a versiones anteriores de iOS? Sí, he usado código similar en juegos de 2.x o 3.x.
agregado el autor zoul, fuente
-1. UIView no es seguro para subprocesos, por lo que debe hacer un montón de otras cosas para que funcione. UIGraphics solo es seguro para subprocesos desde 4.0.
agregado el autor tc., fuente

No sé sobre el iPhone en particular, pero aún puedo ayudar: En lugar de simplemente conectar un retraso fijo al final del ciclo, use lo siguiente:

  • Determine un intervalo de actualización que le complacería y que es más grande que una sola pasada a través de su ciclo principal.
  • Al comienzo del ciclo, tome una marca de tiempo actual de la resolución que tenga disponible y guárdela.
  • Al final del ciclo, tome otra marca de tiempo y determine el tiempo transcurrido desde la última marca de tiempo (inicialice esto antes del ciclo).
  • suspensión/retraso para la diferencia entre el tiempo de fotograma ideal y el tiempo transcurrido para el fotograma.
  • En el siguiente cuadro, incluso puede intentar compensar las imprecisiones en el intervalo de sueño comparando con la marca de tiempo al comienzo del ciclo anterior. Almacene la diferencia y sume/reste del intervalo de sueño al final de este ciclo (el tiempo de espera/retraso puede ser demasiado largo O demasiado corto).

Es posible que desee tener un mecanismo de alerta que le permita saber si su tiempo es demasiado estrecho (es decir, si su tiempo de sueño después de todas las compensaciones es menor a 0, lo que significa que le está tomando más tiempo procesar que tu velocidad de cuadro lo permite). El efecto será que tu juego se ralentiza. Para obtener puntos adicionales, es posible que desee simplificar el procesamiento por un tiempo, si detecta que esto sucede, hasta que tenga suficiente capacidad libre de nuevo.

0
agregado

Use CADisplayLink, puede encontrar cómo en el proyecto de plantilla de OpenGL ES provisto en XCODE (cree un proyecto a partir de esta plantilla y eche un vistazo a la clase EAGLView, este ejemplo se basa en GL abierta, pero puede usar CADisplayLink solo para otra tipo de juegos

0
agregado