Creo que este es el quebradero de cabeza para todos los que comienzan o han comenzado a usar Cocos2D. Usualmente queremos meter en un tabbar de una app tradicional Uikit una aplicación desarrollada en Cocos2D (u otras) y lo único que podemos hacer es levantar un puño al cielo y maldecir en voz alta, eso, o gritar ¡NO SÉ QUE HACER!.
Lo sé, been there done that. Sin embargo, a medida que vas “toqueteando” la herramienta, te das cuenta de lo esencial: El Director ha de instanciarse en el AppDelegate, porque es la BASE de Cocos2D, es quién dirige y dice cuando debe ejecutarse cualquier escena de la app.
AppDelegate.h
#import "uikit.h" #import "General.h" @class RootViewController; @interface AppDelegate : NSObject{ UIWindow *window; RootViewController *viewController; General *general; NSNotificationCenter *notifyCenter; } @property (nonatomic, retain) NSNotificationCenter *notifyCenter; @property (nonatomic, retain) General *general; @property (nonatomic, retain) UIWindow *window; - (void) showUIViewController:(UIViewController *) controller; - (void) hideUIViewController:(UIViewController *) controller; @end
General es la clase UIViewController, donde hemos creado el Tab Bar Controller.
- NSNotificacionCenter es utilizada para, como su nombre lo indica, realizar notificaciones desde cualquier lugar de la app e indicarle al Director en el AppDelegate que debe ejecutar tal o cual escena de Cocos2D.
- RootViewController es el controlador root que Cocos2D utiliza para manejar las rotaciones del iPhone/iPod/iPad.
- window una UIWindow que funcionará para comunicarse con el Director y darle la información de la ventana del dispositivo.
AppDelegate.m
self.notifyCenter = [NSNotificationCenter defaultCenter]; [notifyCenter addObserver:self selector:@selector(trackNotifications:) name:nil object:nil];
window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; [window setUserInteractionEnabled:YES]; [window setMultipleTouchEnabled:YES]; CCDirector *director = [CCDirector sharedDirector]; // Create an EAGLView with a RGB8 color buffer, and a depth buffer of 24-bits EAGLView *glView = [EAGLView viewWithFrame:[window frame] kEAGLColorFormatRGBA8 depthFormat:0]; [glView setMultipleTouchEnabled:YES]; // attach the openglView to the director [director setOpenGLView:glView]; // Enables High Res mode (Retina Display) on iPhone 4 and maintains low res on all other devices if( ! [director enableRetinaDisplay:YES] ) CCLOG(@"Retina Display Not supported"); // make the OpenGLView a child of the main window [window addSubview:glView]; // make main window visible [window makeKeyAndVisible];
2.- Creamos una clase CCScene , en el código se llama GameScene, que no contendrá nada de código excepto por el que viene por defecto con la misma clase, solo servirá para que el Director sepa que es lo que deberá ejecutar, es como un cascarón o wrapper en Cocos2D. Luego instanciamos en el applicationDidFinishLaunching.
Ojo, escribo los comentarios dentro del código en inglés por comodidad y costumbre.
//This must be a CCScene Class, the Director will start to use Cocos2D GameScene *gs = [GameScene node]; [[CCDirector sharedDirector] runWithScene:gs];
3.- Al final del applicationDidFinishLaunching hacemos llamada a un XIB que contiene el Tab Bar Controller
//uiview to be opened General *principal; principal = [[General alloc] initWithNibName:@"General" bundle:nil]; self.general = principal; [principal release];
4.- Y por último hacemos la llamada al UIview
[self showUIViewController:general];
Método de Notificación: trackNotifications
- (void) trackNotifications: (NSNotification *) notification{ id nname = [notification name]; if([nname isEqual:@"empezarPrueba"]){ [self hideUIViewController:general]; // Obtain the shared director in order to... CCDirector *director = [CCDirector sharedDirector]; // Sets landscape mode [director setDeviceOrientation:kCCDeviceOrientationLandscapeLeft]; //CCDeviceOrientationPortrait // Turn on display FPS [director setDisplayFPS:NO]; // Turn on multiple touches EAGLView *view = [director openGLView]; [view setMultipleTouchEnabled:YES]; // Default texture format for PNG/BMP/TIFF/JPEG/GIF images // It can be RGBA8888, RGBA4444, RGB5_A1, RGB565 // You can change anytime. [CCTexture2D setDefaultAlphaPixelFormat:kCCTexture2DPixelFormat_RGBA8888]; [[CCDirector sharedDirector] pushScene: [CCTransitionMoveInB transitionWithDuration:0.0f scene [HelloWorldLayer scene]]]; } }
Clase General
#import "uikit.h" @interface General : UIViewController { IBOutlet UITabBarController *rootController; } @property (nonatomic, retain) IBOutlet UITabBarController *rootController; @end
Es el código que se crea por defecto, de hecho no hay que hacer nada más en el .h ni nada más en el .m.
Clase PreJuego
#import "uikit.h" @interface PreJuego : UIViewController { } - (IBAction) empezarprueba: (id)sender; @end
- (IBAction) empezarprueba:(id)sender{ [[NSNotificationCenter defaultCenter] postNotificationName:@"empezarPrueba" object:@""]; }