
Ya tenemos instalado Xcode junto a las plantillas de cocos2d asi que … ¿para que esperar más?. Comencemos este 2011 creando nuestro primer proyecto en cocos2d.
Abre Xcode y pulsa en File – New Project para crear un nuevo proyecto. Verás una pantalla similar a la siguiente:

Elige la primera opción «cocos2d Application» y en el momento que te pida el nombre del proyecto puedes llamarlo «HelloCocos2D«.
Te deberá aparecer una ventana como la siguiente:

Si te aparece en la parte superior derecha «Base SDK Missing» no podrás compilar pero no te preocupes no es un problema grave. Este caso puede darse según con que versiones del SDK y de cocos2d se trabaje. Por ejemplo, si usas el SDK 4 y versiones antiguas de cocos2d pensadas para el SDK 3 puede ocurrirte.
¿Cómo solucionamos esto?
La solución es fácil. En el menu de Xcode pulsa sobre «Project». A continuación, sobre la opción «Edit Project Settings«. Verás algo similar a lo siguiente:

En la parte superior verás que una de las opciones es «Base SDK for All Configurations» y el valor que debe de tener será algo similar a «Iphone Device X.X(missing)» donde X.X es la versión. Cambia el valor de esto por una versión del SDK más actual. Cierra la ventana.Problema resuelto.
Tras solucionar el problema podrás compilar. Vamos a compilar y ejecutar el proyecto para ver el resultado en el simulador.
Para ello pulsa sobre el botón «Build and Run«.

Tras pulsar sobre dicho botón el simulador del iphone se ejecutará mostrando algo similar a lo siguiente:
Increíble, ¿no?. No hemos escrito ni una sola línea y ya tenemos un Hola Mundo. Con lo realizado hasta ahora podrás darte cuenta de la ventaja que suponen las plantillas ya que como podrás ver nos dan una base bastante buena desde la que partir.
A continuación vamos a intentar entender todo lo que trae un proyecto base (plantilla – template), su significado y funcionamiento.
A lo largo del curso iremos viendo más código y ejemplos que teoría pero en aquellos casos en los cuales la teoría es 100% necesaria pues . . . no hay mas remedio que la veamos. Este es uno de esos casos.
¿Qué ha ocurrido al compilar y ejecutar el proyecto?
La aplicación se instala en el simulador y antes de arrancar vemos su icono en el SpringBoard del mismo. A continuación arranca y nos muestra una ventana de carga con una imágen del logo de cocos2d.
Entonces se crea un CCLabel (ya veremos que es no te preocupes por ahora) con el texto «Hello World». Es lo único que se muestra junto a unos dígitos en la parte inferior izquierda mostrandonos en número de fps (frames por segundo) a los que corre la aplicación.
Ya sabes en esencia que hace el proyecto, veamos el código.
Si ya has trabajado con Xcode sabrás esto perfectamente pero si no es el caso, por defecto, todos los ficheros del proyecto los encuentras en un menu situado a la izquierda llamado «Groups & Files«. Es decir, algo similar a lo que puedes ver a continuación:

En la carpeta llamada «cocos2d Sources» se encuentra todo el código correspondiente al engine. No es necesario ni que te molestes en mirar que hay dentro ya que nunca será realmente necesario. Sin embargo, recuerda que el engine el open source y gratuito asi que si te ves con la curiosidad de mirarlo todo ó si necesitas cambiar algo para adaptar el engine a tus necesidades, no dudes ni un instante, hazlo.
La carpeta «Resources» es la que contendrá todos los recursos gráficos y del cualquier otro tipo que no sea código fuente.
Creo interesante resaltar que la imagen con el nombre «Default.png» en la carpeta Resources será la que se muestre a la hora de cargar la aplicación.
En la carpeta Resources también encontrarás siempre un fichero llamado Info.plist. De momento basta saber que es un archivo de configuración del proyecto y que no se modificará apenas al menos hasta la hora de la publicación del juego.
El código en si del proyecto, donde trabajarás y añadiras elementos será dentro de la carpeta llamada «Classes«.
Dentro de la carpeta hay dos clases (cada una con su archivo .h y .m). Una de ellas es HelloCocos2DAppDelegate que se encarga de configuraciones globales del juego (mostrar o no fps, si se ejecuta en horizontal o vertical, etc) y la otra HelloCocos2DScene que es la que crea el CCLabel que se muestra.
HelloCocos2DAppDelegate
Toda aplicación IOS tiene una clase AppDelegate. Como habrás deducido esta clase es vital y se encarga de multiples funciones como capturar mensajes del sistema (por ejemplo cuando se recibe una llamada), inicializar valores globales de la aplicación, etc.
En esta clase se encuentra el método applicationDidFinishLaunching donde se suele poner el código de inicialización de cocos2d.
Veamos el código:
- (void) applicationDidFinishLaunching:(UIApplication*)application
{
// Init the window
window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
// cocos2d will inherit these values
[window setUserInteractionEnabled:YES];
[window setMultipleTouchEnabled:YES];
// Try to use CADisplayLink director
// if it fails (SDK < 3.1) use the default director
if( ! [CCDirector setDirectorType:CCDirectorTypeDisplayLink] )
[CCDirector setDirectorType:CCDirectorTypeDefault];
// Use RGBA_8888 buffers
// Default is: RGB_565 buffers
[[CCDirector sharedDirector] setPixelFormat:kPixelFormatRGBA8888];
// Create a depth buffer of 16 bits
// Enable it if you are going to use 3D transitions or 3d objects
// [[CCDirector sharedDirector] setDepthBufferFormat:kDepthBuffer16];
// Default texture format for PNG/BMP/TIFF/JPEG/GIF images
// It can be RGBA8888, RGBA4444, RGB5_A1, RGB565
// You can change anytime.
[CCTexture2D setDefaultAlphaPixelFormat:kTexture2DPixelFormat_RGBA8888];
// before creating any layer, set the landscape mode
[[CCDirector sharedDirector] setDeviceOrientation:CCDeviceOrientationLandscapeLeft];
[[CCDirector sharedDirector] setAnimationInterval:1.0/60];
[[CCDirector sharedDirector] setDisplayFPS:YES];
// create an openGL view inside a window
[[CCDirector sharedDirector] attachInView:window];
[window makeKeyAndVisible];
[[CCDirector sharedDirector] runWithScene: [HelloWorld scene]];
}
Las líneas más importantes aquí serían:
[[CCDirector sharedDirector] setDeviceOrientation:CCDeviceOrientationLandscapeLeft];
[[CCDirector sharedDirector] setAnimationInterval:1.0/60];
[[CCDirector sharedDirector] setDisplayFPS:YES];
Lo primero que debemos observar es que se utiliza en todas ellas CCDirector. La clase CCDirector es la principal para el trabajo con las escenas (scenes, ya las veremos mejor más adelante). CCDirector es el encargado también de inicializar OpengGL ES.
NOTA: Habrás observado también que todas las clases pertenecientes a cocos2d comienzan por el prefijo «CC». Es así simplemente para evitar problemas con nombres de clases, etc.
La primera de las líneas anteriores define la orientación del dispositivo. En este caso el dispositivo esta en horizontal y se usa la orientación CCDeviceOrientationLandscapeLeft.
Existen cuatro tipos diferentes de orientación:
– CCDeviceOrientationPortrait
– CCDeviceOrientationPortraitUpsideDown
– CCDeviceOrientationLandscapeLeft
– CCDeviceOrientationLandscapeRight
Ya que es cambiar un tipo por otro te recomiendo que en un instante y para que te quede más claro pruebes a cambiar en el ejemplo de HelloCocos2D cada una de ellas.
La segunda línea define cada cuanto tiempo cocos2d debe refrescar la pantalla. El límite superior son 60 frames por segundo (1.0/60).
La última de las líneas es muy útil para medir el rendimiento de nuestor juego. Nos permite habilitar o deshabilitar si mostramos los FPS.
También debemos resaltar las siguientes líneas:
// Try to use CADisplayLink director
// if it fails (SDK < 3.1) use the default director
if( ! [CCDirector setDirectorType:CCDirectorTypeDisplayLink] )
[CCDirector setDirectorType:CCDirectorTypeDefault];
En cocos2d existen cuatro tipos diferentes de CCDirector:
– NSTimer Director.
– Mainloop Director.
– ThreadMainLoop Director.
– DisplayLink Director: Sólo disponible desde el SDK 3.1 ó superior. Es el usado por defecto.
Con lo visto anteriormente ya sabrás que sencillamente se pone un if para comprobar la versión del SDK en la que se ejecuta para utilizar un CCDirector u otro.
Lo último que vamos a ver en esta clase es como se lanzan las escenas, como se pausan, reanudan, etc. Vamos a ver una visión muy por encima del concepto. En futuras entradas del curso veremos como controlar todo esto mejor, pudiendo pausar el juego ó mostrar un mensaje al realizar estas acciones.
- (void)applicationWillResignActive:(UIApplication *)application{
[[CCDirector sharedDirector] pause];
}
Este método nos lo ha puesto directamente la plantilla (insisto para que quede constancia de lo increiblemente bien que están diseñadas). Cuando el juego se para por ejemplo por que la pantalla se ha bloqueado se llama a este método. Para todo lo necesario, pone los FPS a cero y el consumo de CPU se reduce.
Por el contrario, te estarás preguntando . . . ¿Qué ocurre si el juego de reactiva? (siguiendo el ejemplo anterior, la pantalla se desbloquea). Pues que se llama al siguiente método:
- (void)applicationDidBecomeActive:(UIApplication *)application{
[[CCDirector sharedDirector] resume];
}
HelloWorldScene
Se ha nombrado ya en un par de ocasiones las escenas (scene – CCScene) pero aún no sabes que es.
El concepto de CCScene es sencillo. No es más que un «contenedor» donde añadir elementos visuales (como los sprites a usar en el juego) basandonos en un eje de coordenadas. Un CCScene hace poco por si sólo.
Aprovechamos para introducir el concepto de CCLayer. Una escena (CCScene) puede contener tantos CCLayer como necesitemos. Para que su concepto sea fácil de entender imaginate que estas en un programa de edición fotográfica donde cada imagen puede contener multiples capas. Cada capa sería un CCLayer en esta ocasión.
El CCLayer es el encargado de capturar los eventos del acelerómetro y los toques en la pantalla.
Tanto el CCLayer como el CCScene (además de otros que usaremos en futuras entradas como CCSprite) son subclases de CCNode. Podemos decir de forma clara que todo elemento visual o que contenga un elemento visual es en el fondo un CCNode.
CCNode es una clase abstracta sin representación visual.
¿Porque derivan tantas clases de CCNode?
Fácil, la mayoría de métodos y propiedades comunes a todos los elementos visuales está definido en CCNode. Los métodos propios de cada elemento (por ejemplo como se debe o no mostrar cada uno) se definen en los hijos. De esta forma se factoriza mucho código.
Veamos el código:
// on "init" you need to initialize your instance
-(id) init
{
// always call "super" init</pre>
// Apple recommends to re-assign "self" with the "super" return value
if( (self=[super init] )) {
// create and initialize a Label
CCLabel* label = [CCLabel labelWithString:@"Hello World" fontName:@"Marker Felt" fontSize:64];
// ask director the the window size
CGSize size = [[CCDirector sharedDirector] winSize];
// position the label on the center of the screen
label.position = ccp( size.width /2 , size.height/2 );
// add the label as a child to this Layer
[self addChild: label];
}
return self;
}
El método anterior es el llamado nada mas inicializar el layer. Es en él donde se crea un CCLabel con el contenido «Hello World». Un CCLabel no tiene mucha explicación. Equivale al Label existente en el resto de la mayoría de lenguajes de programación. Es decir, es un objeto que permite mostrar un texto.
Tras crear el CCLabel se toma el tamaño de la pantalla gracias al CCDirector (si estamos en un iphone ó ipod touch será 480 * 320 px. Si por el contrario es un ipad será de 1024 * 768 px).
A continuación, situamos al label en mitad de la pantalla. Para ello se usa un macro interno de cocos2d sencillamente usando ccp. Esto nos creará un CGPoint de una forma más rápida y directa. Veremos mas macros de cocos2d a lo largo del curso. Quedate con la idea, puedes usarlos o no, sencillamente nos facilitan las vida escribiendo menos para hacer lo mismo.
Podéis obtener el código fuente de lo visto en esta entrada realizando clic aquí.
Llegamos al final de la entrada de hoy. Como verás se ha avanzado y aprendido bastante sobre las bases de cocos2d.
La siguientes entradas serán más interesantes aún. Veremos como mostrar sprites en pantalla, como colocar un fondo para el juego (de momento estático, en futuras entradas haremos que se mueva, ideal por ejemplo para los típicos juegos de naves) y mucho más.