Nuevos objetivos :: Cocos2D
Bueno …. realmente tras muchos quebraderos de cabeza con el xcode en general (y con el Interface Builder en particular) puedo decir que ya me he cansado. Hace tiempo descubrí cocos2d y aunque al principio no me pareció interesante tengo que decir que ya ha llegado a un nivel de madurez notable y hoy vamos a pasarnos a usar este framework:

Descarga e instalación
Empezamos por ir a la web del cocos2D y dentro de la sección Descargas podemos encontrar la ultima versión, a fecha de hacer esta entrada era la 0.99.5 Release candidate 0 y como esto suele cambiar bastante rápido aquí os cuelgo un mirror:
cocos2d-iphone-0.99.5-rc0.tar.gz (19.51 Mb)
Actualización 16/11/2010 – Acaban de publicar la Release Candidate 1, que según especifican será la ultima RC antes de la versión Final, asi que ya que estamos nos pasamos a esta versión
cocos2d-iphone-0.99.5-rc1.tar.gz (29.15 Mb)
Otra actualización 16/12/2010 – Versión oficial 0.99.5
cocos2d-iphone-0.99.5.tar.gz (29.82 Mb)
Una vez descargado lo descomprimimos en cualquier sitio (es decir, en el escritorio) y vamos a instalarlo … de momento la instalación se hace desde línea de comandos, no se si esto lo cambiarán alguna vez, aunque tampoco nos va a suponer ninguna complicación: Abrimos un terminal y vamos al directorio donde hayamos descomprimido el paquete, y lanzamos el script de instalación, en nuestro caso:
| C | | copy code | | ? |
| 1 | cd Desktop/cocos2d-iphone-0.99.5-rc0 |
| 2 | sudo ./install_templates.sh |
Nos deberá salir un log de todo el copiado de archivos que hace, según la documentación se le puede pasar a esto un parámetro para especificar un directorio distinto de instalación en caso que vuestro Xcode esté en otro sitio.
Actualización 16/11 – Con la nueva Release Candidate será necesario reinstalar los templates, para ello debéis ejecutar el script install_templates.sh con el parámetro -f para forzar la instalación. Sino detecta que ya tenéis esta versión y no hará nada
| C | | copy code | | ? |
| 1 | cd Desktop/cocos2d-iphone-0.99.5-rc1 |
| 2 | sudo ./install_templates.sh -f |
Si todo ha funcionado correctamente podemos abrir el Xcode y veremos que al crear un nuevo proyecto tendremos unos simpáticos templates nuevos:
Hello World
Ok … el siguiente paso será crear un proyecto y compilar para ver el resultado, por defecto el template base de cocos2d es un Hello World así que los pasos hasta aquí van a ser fáciles:
Empezamos por crear un proyecto partiendo del template base que nos da cocos2d y lo llamamos HelloWorld, luego cuando se nos abra el proyecto deberemos ajustar el SDK con el que queremos compilar, por defecto el cocos2d nos marca los proyectos para compilar con el SDK 4.1, y en mi caso no hay problema, pero en caso de no tener este SDK veremos este error con lo que no podremos compilar. Deberemos modificar el SDK base para especificar otro que si tengamos:
Para ello vamos a propiedades del proyecto, y en la pestaña Build modificamos el Base SDK, en esta misma ventana que nos aparece ya nos indica que SDK tenemos disponibles. Una vez modificado ya nos aparecerá correcto en la ventana del proyecto y podremos seleccionar que nos lo ejecute en el simulador.
Una vez ajustado esto podemos compilar el ejemplo, y si todo sale bien deberíamos obtener algo parecido a esto:
Pronto nos acostumbraremos al contador de Frames que pone el cocos2d en sus proyectos (y ya veremos luego como desactivarlo).
Primera pruebas
Como esto compila y hasta funciona vamos a hacer una pequeña modificación para ver lo sencillo que nos va a resultar jugar con este framework:
Solo haremos 2 modificaciones. Empezaremos por ir al archivo HelloWorld.h y añadimos una variable a la clase:
| C | | copy code | | ? |
| 1 | @interface HelloWorld : CCLayer |
| 2 | { |
| 3 | CCSprite *player; |
| 4 | } |
A continuación nos vamos a la clase ‘HelloWorld.m’ y modificamos el metodo init dejando esto:
| C | | copy code | | ? |
| 01 | -(id) init { |
| 02 | if( (self=[super init] )) { |
| 03 | CGSize winSize = [[CCDirector sharedDirector] winSize]; |
| 04 | |
| 05 | // Creamos un Sprite a partir de 'Icon.png' y lo ponemos en el centro de la pantalla |
| 06 | player = [CCSprite spriteWithFile:@"Icon.png"]; |
| 07 | player.position = ccp(winSize.width/2, winSize.height/2); |
| 08 | [self addChild:player]; |
| 09 | |
| 10 | // Activamos el Touch |
| 11 | self.isTouchEnabled = YES; |
| 12 | } |
| 13 | return self; |
| 14 | } |
Con esto ya podríamos compilar y veríamos nuestro sprite en el centro de la pantalla … pero ya que estamos vamos a hacer un poquito mas … añadimos un metodo para controlar el Touch
| C | | copy code | | ? |
| 01 | - (void)ccTouchesEnded:(NSSet *)touches withEvent:(UIEvent *)event { |
| 02 | |
| 03 | // Sacamos un touch de la pila, el primero |
| 04 | UITouch *touch = [touches anyObject]; |
| 05 | CGPoint location = [touch locationInView:[touch view]]; |
| 06 | |
| 07 | // lo convertimos a coordenadas GL |
| 08 | location = [[CCDirector sharedDirector] convertToGL:location]; |
| 09 | |
| 10 | // determinamos el punto destino donde movernos y la velocidad |
| 11 | CGPoint pointDest = ccp(location.x, location.y); |
| 12 | float MoveDuration = 0.5f; |
| 13 | |
| 14 | // Creamos la accion y se la damos al player |
| 15 | id action = [CCMoveTo actionWithDuration:MoveDuration position:pointDest]; |
| 16 | [player runAction:action]; |
| 17 | } |
Como el código ya tiene comentarios no hace falta explicar mucho mas … solo que los Actions parecen complicados y por lo poco que he trasteado con ellos os puedo decir que lo son. Y ahora el video !!!
ala, fin!!! solo falta el proyecto para los mas vagos
cocos2d FirstApplication (689.5 Kb)
Como todo ha sido facil vamos a ver que pasa si añadimos algún detalle nuevo, hemos creado una acción simple, diciéndole al sprite el movimiento que debe hacer, pero a partir de ese momento ya no controlamos el movimiento ni sabemos donde está ni sabemos cuando termina. Vamos a modificar el método para añadir un evento y decirle al sprite que nos llave a un evento cuando este termine su movimiento:
| C | | copy code | | ? |
| 01 | |
| 02 | // Creamos la acción, exactamente igual que antes |
| 03 | id action = [CCMoveTo actionWithDuration:MoveDuration position:pointDest]; |
| 04 | |
| 05 | // creamos este evento para que nos llame a 'spriteMoveFinished' |
| 06 | id evento = [CCCallFuncN actionWithTarget:self selector:@selector(spriteMoveFinished:)]; |
| 07 | |
| 08 | // y le decimos al sprite que se mueva |
| 09 | [player runAction:[CCSequence actions:action,evento,nil]]; |
| 10 |
Ahora al runAction del sprite le vamos a dar una secuencia de acciones, el sprite las ejecutará en el orden que se las demos, primero el movimiento y cuando este termine lanzará el evento que le hemos dado. De esta forma podemos implementar el metodo ‘spriteMoveFinished’
| C | | copy code | | ? |
| 01 | |
| 02 | -(void)spriteMoveFinished:(id)sender { |
| 03 | // Este metodo nos pasa como parametro el SPRITE que lo llama, aunque nosotros |
| 04 | // ya sabemos que es nuestro player, pero en condiciones normales estos metodos |
| 05 | // se usarán para muchos mas sprites |
| 06 | CCSprite *sprite = (CCSprite *)sender; |
| 07 | |
| 08 | // sacamos las coordenadas X Y del sprite |
| 09 | int x = sprite.position.x; |
| 10 | int y = sprite.position.y; |
| 11 | } |
Vamos a añadir algún efecto cuando el sprite termine su movimiento … para ello en el momento que termine su animación crearemos nuevos objetos .. con sus acciones y con su correspondiente evento:
| C | | copy code | | ? |
| 01 | |
| 02 | -(void)spriteMoveFinished:(id)sender { |
| 03 | CCSprite *sprite = (CCSprite *)sender; |
| 04 | int x = sprite.position.x; |
| 05 | int y = sprite.position.y; |
| 06 | |
| 07 | // creamos 6 Stars |
| 08 | [self BuildStars:5 x:x y:y radius:100]; |
| 09 | } |
| 10 | |
| 11 | -(void) BuildStars:(int)count x:(int)x y:(int)y radius:(int)radius |
| 12 | { |
| 13 | int angle; |
| 14 | for(angle=0;angle<count;angle++) |
| 15 | { |
| 16 | CCSprite *star = [CCSprite spriteWithFile:@"Star.png"]; |
| 17 | star.position = ccp(x,y); |
| 18 | star.scale = 0.5f; |
| 19 | |
| 20 | float fx = cosf(angle*(360/count)*0.0174) * radius; |
| 21 | float fy = sinf(angle*(360/count)*0.0174) * radius; |
| 22 | |
| 23 | CGPoint pointDest = ccp(x+fx,y+fy); |
| 24 | |
| 25 | id action = [CCMoveTo actionWithDuration:1 position:pointDest]; |
| 26 | id ease = [CCEaseExponentialOut actionWithAction:action]; |
| 27 | id fadeout = [CCFadeOut actionWithDuration:0.2f]; |
| 28 | id evento = [CCCallFuncN actionWithTarget:self selector:@selector(starMoveFinished:)]; |
| 29 | |
| 30 | [star runAction:[CCSequence actions: ease, fadeout, evento, nil]]; |
| 31 | [self addChild:star]; |
| 32 | } |
| 33 | } |
| 34 | |
| 35 | -(void)starMoveFinished:(id)sender { |
| 36 | CCSprite *star = (CCSprite *)sender; |
| 37 | [self removeChild:star cleanup:YES]; |
| 38 | } |
| 39 |
Cosas interesantes que podemos ver aqui … vereis como se crean 6 estrellas y se les añaden acciones nuevas, de esta forma creamos el movimiento decelerado que tiene la estrella:
| C | | copy code | | ? |
| 1 | id action = [CCMoveTo actionWithDuration:1 position:pointDest]; |
| 2 | id ease = [CCEaseExponentialOut actionWithAction:action]; |
Si consultais los CCEase veréis que hay muuuucha variedad de movimientos, probar los Elastic y veréis que vicio. (Nota!!! no todos los CCEase tienen los mismos parámetros).
Tras el movimiento hacemos que la estrella desaparezca mediante un FadeOut
| C | | copy code | | ? |
| 1 | id fadeout = [CCFadeOut actionWithDuration:0.2f]; |
Y tras estas acciones le añadimos un evento para que la estrella se elimine de nuestro juego
| C | | copy code | | ? |
| 1 | CCSprite *star = (CCSprite *)sender; |
| 2 | [self removeChild:star cleanup:YES]; |
Aquí el resultado:
Y a continuación el proyecto
cocos2d FirstApplication + Stars !! (714.95 Kb)
4 Comments
neofar on January 22nd, 2011
jeje .. me alegra que te sea de utilidad, a mi realmente el cocos2d me ha impresionado bastante, así que de ahora en adelante la mayoría de tutoriales de la web será sobre cocos2d.
Un saludo
cloyd on February 8th, 2011
saludos muy buenos tutos gracias aunque creo haria falta una introduccion del entorno de cocos y como se implementan las librerias por decir hay veces en el tuto que no se distingue que es codigo para anexar al proyecto y cual es a modo comentario por que ambos tienen opcion copiar y me gustaria pudieras anexar a que file corresponde cada fragmento de codigo nuevamente gracias por el post
neofar on February 10th, 2011
Pues en teoría todo es código por añadir. Este ejemplo era muy básico … en teoría cuando hago algún tutorial mas complejo detallo mejor donde va cada parte del código, de todos modos también suelo incluir el proyecto para descargar.
Pero me anoto el consejo, gracias por el mensaje



@raywenderlich
Cocos 2d
cocos2d-central
libgdx
libgdx-users
Pedro Garrido on January 21st, 2011
Esta realmente excelente tu pagina. Me ha servido de muuuuuuuuuucho. Muchas gracias por compartir tus conocimientos.