Soy nuevo en el desarrollo de iPhone, pero estoy tratando de construir un juego en 2D. Estaba siguiendo un libro, pero el bucle del juego se creó básicamente dije:¿Es esta una buena manera de hacer un ciclo de juego para un juego de iPhone?
function gameLoop
update()
render()
sleep(1/30th second)
gameLoop
El razonamiento era que esto iría a 30 fps. Sin embargo, esto parecía un poco mental, porque si mi fotograma tuviese 1/30 de segundo, funcionaría a 15 fps (ya que pasaría tanto tiempo durmiendo como actualizando).
Así que investigué un poco y encontré la clase CADisplayLink que sincronizaría las llamadas a mi función gameLoop con la frecuencia de actualización (o una fracción de ella). No puedo encontrar muchas muestras de él, así que estoy publicando aquí para una revisión del código :-) Parece que funciona como se esperaba, e incluye pasar el tiempo transcurrido (fotograma) al método de actualización para que mi lógica pueda ser una tasa de fotogramas -independiente (sin embargo, en realidad no puedo encontrar en el documento lo que CADisplayLink haría si mi cuadro tomara más tiempo de lo que tenía permitido ejecutar, ¡espero que haga todo lo posible para ponerse al día y no se cuelgue!).
//
// GameAppDelegate.m
//
// Created by Danny Tuppeny on 10/03/2010.
// Copyright Danny Tuppeny 2010. All rights reserved.
//
#import "GameAppDelegate.h"
#import "GameViewController.h"
#import "GameStates/gsSplash.h"
@implementation GameAppDelegate
@synthesize window;
@synthesize viewController;
- (void) applicationDidFinishLaunching:(UIApplication *)application
{
// Create an instance of the first GameState (Splash Screen)
[self doStateChange:[gsSplash class]];
// Set up the game loop
displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(gameLoop)];
[displayLink setFrameInterval:2];
[displayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
}
- (void) gameLoop
{
// Calculate how long has passed since the previous frame
CFTimeInterval currentFrameTime = [displayLink timestamp];
CFTimeInterval elapsed = 0;
// For the first frame, we want to pass 0 (since we haven't elapsed any time), so only
// calculate this in the case where we're not the first frame
if (lastFrameTime != 0)
{
elapsed = currentFrameTime - lastFrameTime;
}
// Keep track of this frames time (so we can calculate this next time)
lastFrameTime = currentFrameTime;
NSLog([NSString stringWithFormat:@"%f", elapsed]);
// Call update, passing the elapsed time in
[((GameState*)viewController.view) Update:elapsed];
}
- (void) doStateChange:(Class)state
{
// Remove the previous GameState
if (viewController.view != nil)
{
[viewController.view removeFromSuperview];
[viewController.view release];
}
// Create the new GameState
viewController.view = [[state alloc] initWithFrame:CGRectMake(0, 0, IPHONE_WIDTH, IPHONE_HEIGHT) andManager:self];
// Now set as visible
[window addSubview:viewController.view];
[window makeKeyAndVisible];
}
- (void) dealloc
{
[viewController release];
[window release];
[super dealloc];
}
@end
Cualquier comentario sería apreciada :-)
PS. Puntos de bonificación si me puede decir por qué todos los libros usan "viewController.view", pero para todo lo demás parece usar el formato "[object name]". ¿Por qué no [viewController view]?
Aunque este código funciona, parece tartamudear un poco. La velocidad de fotogramas no es baja, simplemente no parece suave. Creo que esto puede deberse a que estoy sincronizando con la velocidad de fotogramas y luego * actualizando * en mi bucle de juego. La renderización se realiza en drawRect. Creo que mi código debe dibujarse directamente en el método llamado (y tal vez la actualización se debe hacer después del sorteo), pero no puedo encontrar ningún buen ejemplo de CADisplayLink. –
Cambié el movimiento de mis sprites a 30 píxeles por segundo, y parece completamente suave (con el marco muy ocasional caído), así que creo que fue solo por la velocidad que había establecido, por ejemplo. moviéndose un poco más de un píxel por cuadro, lo que significaba que eventualmente saltaría dos píxeles en un cuadro, lo que lo haría parecer desigual. Supongo que esto es inevitable. –