Krypton Solid

Creando juegos de iPhone realistas con Cocos2D – Smashing Magazine

Creando juegos de iPhone realistas con Cocos2D – Smashing Magazine

La animación hace que los juegos sean reales. El movimiento agrega emoción a un juego y hace que los personajes sean más realistas. En este artículo, veremos la biblioteca Cocos2D y cómo admite animaciones programáticas en juegos de iPhone.

La animación hace que los juegos sean reales. El movimiento agrega emoción a un juego y hace que los personajes sean más realistas. En este artículo, veremos la biblioteca Cocos2D y cómo admite animaciones programáticas en juegos de iPhone.

Este artículo es parte de una serie que le enseña cómo crear juegos para iPhone basado en el juego de código abierto Siete puentes. Asegúrese de consultar el primer artículo de la serie, «Diseño de un juego de código abierto para iPhone» y consulte el código fuente en el Repositorio Seven Bridges GitHub.

Este artículo lo guía a través de los conceptos básicos de la animación. Veremos las acciones en Cocos2D y veremos cómo combinarlas para crear efectos complejos y personalizados.

Acciones simples

Todos los componentes básicos de un juego Cocos2D, como imágenes y capas, se derivan de [CCNode](http://www.cocos2d-iphone.org/api-ref/2.1.0/interface_c_c_node.html). Los nodos interactúan con acciones, que se extienden [CCAction](http://www.cocos2d-iphone.org/api-ref/2.1.0/interface_c_c_action.html) para crear movimiento en la pantalla.

Las acciones básicas de Cocos2D pueden:

  • esconderse y mostrar,
  • voltear y rotar,
  • desvanecimiento y tinte,
  • y mucho más.

Empezaremos mirando la acción simple [CCBlink](http://www.cocos2d-iphone.org/api-ref/2.1.0/interface_c_c_blink.html). Seven Bridges no usa la acción de parpadeo, pero es una de las acciones más fáciles de entender.

Antes de que podamos empezar a utilizar cualquier acción, necesitaremos un nodo. Empezaremos con [PlayerNode](https://github.com/zgrossbart/bridges/blob/master/bridges2/PlayerNode.mm) de Seven Bridges.

El nodo del jugador es simple. Muestra el sprite del jugador, El icono del jugador, y maneja el movimiento y la animación del jugador alrededor de la pantalla. PlayerNode no es en realidad un CCNode, pero contiene un [CCSprite](http://www.cocos2d-iphone.org/api-ref/2.1.0/interface_c_c_sprite.html), que representa una sola imagen y se extiende CCNode. Separar el objeto del jugador de la imagen real del jugador hace que el objeto del jugador sea un poco más flexible.

Nuestro nodo de jugador necesita un color y un [LayerManager](https://github.com/zgrossbart/bridges/blob/master/bridges2/LayerMgr.mm). LayerManager es un objeto de ayuda en Seven Bridges que permite que los nodos del juego interactúen con el mundo que los rodea. No es necesario codificar sus objetos con un LayerManager, pero le brinda un lugar sencillo para agregar código estándar.

Creemos un nuevo jugador y coloque el reproductor en la pantalla.


PlayerNode* player = [[PlayerNode alloc] initWithColor:cBlack layerMgr:_layerMgr];
player.player.position = ccp(100, 100);

PlayerNode contiene el puntero de sprite y usa el LayerManager para agregar el objeto a la escena. Hace que el sprite esté disponible como una propiedad llamada player, que tiene una propiedad llamada position. El código completo para crear LayerManager es en [LevelLayer](https://github.com/zgrossbart/bridges/blob/master/bridges2/LevelLayer.mm).

La acción de parpadeo puede ejecutarse directamente en el sprite del jugador, porque los sprites también son CCNode objetos que implementan el [runAction](http://www.cocos2d-iphone.org/api-ref/2.1.0/interface_c_c_node.html#a5d6d868cc1a0ba72820a055b05661aa5) método. Funciona así:


CCBlink* blink = [CCBlink actionWithDuration:10 blinks:5];
[player.player runAction:blink];

La mayoría de las acciones definen una estática actionWithDuration método, que crea un nuevo objeto de acción. CCBlink toma una duración y el número de veces que debería parpadear. Podemos aplicar las acciones que queramos al nodo con solo pasarlas al runAction método.

Ejecución de varias acciones

La última versión de Seven Bridges presenta teletransportadores, Icono de teletransportador. Cuando los jugadores se encuentran con teletransportadores, deberían parecer que están saltando. Para crear ese efecto, combinaremos tres acciones: rotar, desvanecer y escalar. Cada una de estas acciones tarda un poco en ejecutarse, pero podemos hacer que todas se ejecuten simultáneamente. Póngalos juntos y veremos a los jugadores girar y desaparecer a medida que se encogen (nuevamente, vea LevelLayer.mm).


[player.player runAction:[CCRotateBy actionWithDuration:0.5 angle:360]];
[player.player runAction:[CCFadeTo actionWithDuration:0.5 opacity:0.0]];
[player.player runAction:[CCScaleTo actionWithDuration:0.5 scale:0.25]];

CCRotateBy gira al jugador desde la posición actual en un número específico de grados. En este caso, queremos un círculo completo, por lo que giramos 360 grados.

CCFadeTo cambia la opacidad del jugador al valor especificado. Queremos que los jugadores desaparezcan por completo, así que nos desvanecemos 0.0.

CCScaleTo aumenta o encoge el reproductor de acuerdo con el factor de escala especificado. Queremos que los jugadores se encojan al entrar en el teletransportador., por lo que los reducimos a una cuarta parte del tamaño predeterminado.

Estas acciones tienen una duración, al igual que CCBlink. Al especificar la duración como la misma para cada acción, hacemos que las tres se ejecuten al mismo tiempo. Jugarlos todos juntos se ve así:

Seven Bridges – salto de teletransporte de Zack Grossbart en Vimeo.

Combinar acciones en secuencias

La rotación y el desvanecimiento son geniales, pero vayamos a un nivel superior cambiando las dimensiones del sprite, en lugar de solo el tamaño. El mapa «Casas y colores» presenta casas, Icono de la casa, que tienes que visitar. Cuando visitas una casa, la convertimos en gris con un poco de floritura.

Las casas están representadas por un objeto similar a PlayerNode, llamado [HouseNode](https://github.com/zgrossbart/bridges/blob/master/bridges2/HouseNode.mm). Cada uno es un objeto auxiliar que contiene un objeto y que maneja las interacciones. PlayerNode expone el sprite del jugador en una propiedad llamada player, y HouseNode expone el sprite de la casa en una propiedad llamada house.

La animación de visitas a la casa voltea la casa horizontalmente mientras la vuelve gris. Para voltear la casa de un lado a otro, ejecutamos dos acciones secuencialmente. La primera acción voltea la casa hacia la derecha y la deja al revés. La segunda acción lo voltea hacia la izquierda.

El jugador que giraba, se encogía y se desvanecía usaba tres animaciones que se ejecutaban al mismo tiempo. La casa necesita más control. Para espaciarlos, usaremos un nuevo objeto llamado [CCSequence](http://www.cocos2d-iphone.org/api-ref/2.1.0/interface_c_c_sequence.html). Las secuencias encadenan acciones que se ejecutan una tras otra.

Comenzaremos creando nuestras dos acciones (HouseNode.mm):


float scale = 1.0;
CCEaseExponentialIn* flipHalf = [CCEaseExponentialIn
    actionWithAction:[CCActionTween actionWithDuration:0.25 key:@"scaleX" from:-scale to:0.0]];

CCEaseExponentialOut* flipRemainingHalf = [CCEaseExponentialOut
    actionWithAction:[CCActionTween actionWithDuration:0.25 key:@"scaleX" from:0.0 to:scale]];

Cocos2D proporciona una serie de acciones especiales que hacen facilitación y interpolación posible. Todos derivan de [CCEase](http://www.cocos2d-iphone.org/api-ref/2.1.0/interface_c_c_action_ease.html). Estas acciones brindan acceso simple a algunas de las animaciones de movimiento básicas que hacen que los objetos reboten y se deslicen entre sí con un movimiento más natural. Estas mismas técnicas se utilizan en la Web para animaciones JavaScript.

CCEaseExponentialIn y CCEaseExponentialOut proporcionan un movimiento natural dentro y fuera de varias posiciones utilizando una curva exponencial. Esta animación combina eso con [CCTween](http://www.cocos2d-iphone.org/api-ref/2.1.0/interface_c_c_action_tween.html), que puede aplicar cambios a cualquier propiedad de un nodo. Cambiamos el scaleX propiedad para iniciar la rotación.

¿Confundido todavía?

Aquí hay muchas matemáticas, pero los conceptos básicos son bastante simples. La primera animación hace que la casa se haga más pequeña horizontalmente a lo largo del eje x. Esto aplasta la casa hasta que desaparece. La segunda animación separa la casa desde cero hasta el ancho completo. Cuando los pones juntos, la casa parece estar girando.

Creemos nuestra casa y ejecutemos las animaciones junto con una secuencia como esta (HouseNode.mm):


HouseNode *houseNode = [[HouseNode alloc] initWithColorAndCoins:cBlack layerMgr:layerMgr coins:0];

CCSequence* seq = [CCSequence actions:flipHalf, flipRemainingHalf, nil];
[house runAction:seq];

CCSequence realiza una serie de acciones y las ejecuta una tras otra. El último argumento es una construcción Objective-C llamada selector; define un método para llamar cuando se completan las acciones. Es opcional y no necesitamos ninguna notificación, así que simplemente la pasamos nil.

Combinar acciones con código personalizado

Esta secuencia le dará la vuelta a la casa, pero también queremos que se vuelva gris: Icono de la casa gris. Cocos2D proporciona acciones especiales para teñir, pero queremos una imagen de alta calidad para la casa gris, por lo que usaremos un archivo PNG. Ninguna de las acciones predeterminadas reemplaza la imagen de un sprite, por lo que necesitamos un pequeño código personalizado. Cocos2D proporciona la máxima flexibilidad con la [CCCallFunc](http://www.cocos2d-iphone.org/api-ref/2.1.0/interface_c_c_call_func.html) action, que se encuentra dentro de una secuencia y llama a cualquier código que desee.

La casa se vuelve gris cuando finaliza la visita, así que crearemos una nueva función llamada visitEnded y definirlo en HouseNode, al igual que (HouseNode.mm):


-(void)visitEnded {
    CCSpriteFrameCache* cache = [CCSpriteFrameCache sharedSpriteFrameCache];
    CCSpriteFrame* frame;
    frame = [cache spriteFrameByName:@"house_gray.png"];
    [self.house setDisplayFrame:frame];
}

Ya tenemos un icono de casa gris, por lo que visitEnded La función obtiene ese ícono del caché de sprites y lo coloca en nuestro house duende. Ahora solo necesitamos ajustar nuestra secuencia para llamar visitEnded en medio de la animación. Este código se está volviendo un poco complicado, así que lo agregaremos a un nuevo método en HouseNode y llámalo visit.


-(void) visit {
    float scale = 1.0;
    CCEaseExponentialIn* flipHalf = [CCEaseExponentialIn
        actionWithAction:[CCActionTween actionWithDuration:0.25 key:@"scaleX" from:-scale to:0.0]];

    CCEaseExponentialOut* flipRemainingHalf = [CCEaseExponentialOut
        actionWithAction:[CCActionTween actionWithDuration:0.25 key:@"scaleX" from:0.0 to:scale]];

    CCSequence* seq = [CCSequence actions:flipHalf,
                      [CCCallFunc actionWithTarget:self selector:@selector(visitEnded)],
                      flipRemainingHalf, nil];

    [self.house runAction:seq];
}

Esta nueva secuencia aplastará la casa, llama a visitEnded método con CCCallFunc para convertir la casa en gris y estirarla hacia afuera.

Seven Bridges – Visita a la casa de Zack Grossbart en Vimeo.

Cocos2D proporciona una serie de acciones para llamar a código personalizado, como [CCCallFuncN](http://www.cocos2d-iphone.org/api-ref/2.1.0/interface_c_c_call_func_n.html) y [CCCallBlock](http://www.cocos2d-iphone.org/api-ref/2.1.0/interface_c_c_call_block.html). Cada uno es una variación de llamar al código personalizado durante las secuencias. La combinación de animaciones listas para usar con código personalizado crea un entorno ideal para animaciones complejas.

Combinando múltiples animaciones en sistemas de partículas

Hemos analizado animaciones sencillas y hemos analizado algunas interacciones más complejas. Ahora pongámonos elegantes con las partículas. Cocos2D proporciona un conjunto de animaciones más complejas, que comienzan con [CCParticleSystem](http://www.cocos2d-iphone.org/api-ref/2.1.0/interface_c_c_particle_system.html).

Los sistemas de partículas no son acciones. Usan acciones para crear animaciones enlatadas flexibles. Son asombrosos, complejos y mal documentados. Los sistemas de partículas funcionan bien para imitar fenómenos naturales. como lluvia y humo.

Cuando superas un nivel de Seven Bridges, te damos una pequeña recompensa: confeti en forma de estrella que gira y flota por la pantalla. Agregamos fantasía a esas estrellas con algo de aleatoriedad, y juntamos todo con un sistema de partículas llamado [CCParticleRain](http://www.cocos2d-iphone.org/api-ref/2.1.0/interface_c_c_particle_rain.html).

Siete puentes – estrellas de Zack Grossbart en Vimeo.

Entonces … um … no hay forma de entrar fácilmente en este, aquí hay una gran parte de código (LevelLayer.mm):


-(void) showConfetti: (float) x y:(float) y {
    self.emitter = [[CCParticleRain alloc] init];
    [self.emitter setScaleX:0.5];
    [self.emitter setScaleY:0.5];

    [self.emitter resetSystem];
    self.emitter.texture = [[CCTextureCache sharedTextureCache] addImage:@"confetti.png"];

    self.emitter.duration = 1.5;

    // Set the gravity effect for the stars to control how
    // fast they fall down.
    self.emitter.gravity = ccp(self.player.player.position.x, 90);

    // Specify the angle of the stars as they extend from the
    // starting point.
    self.emitter.angle = 90;
    self.emitter.angleVar = 360;

    // The speed the particles will use when floating
    self.emitter.speed = 160;
    self.emitter.speedVar = 20;

    // The radial variable
    self.emitter.radialAccel = -120;
    self.emitter.radialAccelVar = 120;

    // The tangential variable
    self.emitter.tangentialAccel = 30;
    self.emitter.tangentialAccelVar = 60;

    // How long each star should last before fading out
    self.emitter.life = 1;
    self.emitter.lifeVar = 4;

    // How much each star should spin
    self.emitter.startSpin = 15;
    self.emitter.startSpinVar = 5;
    self.emitter.endSpin = 360;
    self.emitter.endSpinVar = 180;

    // The color of the stars as RGB values.  Each color uses
    // a variable value for where the stars should start and
    // what color they should use when they're done.
    ccColor4F startColor = {171.0f, 26.0f, 37.0f, 1.0f};
    self.emitter.startColor = startColor;
    ccColor4F startColorVar = {245.0f, 255.f, 72.0f, 1.0f};
    self.emitter.startColorVar = startColorVar;
    ccColor4F endColor = {255.0f, 223.0f, 85.0f, 1.0f};
    self.emitter.endColor = endColor;
    ccColor4F endColorVar = {255.0f, 131.0f, 62.0f, 1.0f};
    self.emitter.endColorVar = endColorVar;

    // The size of each of the stars
    self.emitter.startSize = 50.0f;
    self.emitter.startSizeVar = 20.0f;
    self.emitter.endSize = kParticleStartSizeEqualToEndSize;

    // The rate at which new stars will be created
    self.emitter.totalParticles = 250;
    self.emitter.emissionRate = self.emitter.totalParticles/self.emitter.life;

    // The position to start the stars
    self.emitter.posVar = ccp(x + 20, y - 20);
    self.emitter.position = ccp(x,y);

    // We have a simple white background, so we don't want to
    // do additive blending.
    self.emitter.blendAdditive = NO;

    // Now we're ready to run the particle emitter
    [self addChild: self.emitter z:10];
    self.emitter.autoRemoveOnFinish = YES;

    // We call the doWon function when the particle system completes
    // so that we can take the player to the You Won screen.
    [self scheduleOnce:@selector(doWon) delay:3];
}

Este código proviene de [LevelLayer](https://github.com/zgrossbart/bridges/blob/master/bridges2/LevelLayer.mm), que controla las interacciones del jugador con la pantalla de juego. Cuando el jugador gana el nivel, llamamos al showConfetti método y pase en la ubicación actual del jugador.

El sistema de partículas comienza con una sola imagen, Icono de confeti estrella, crea cientos de instancias de esa imagen y mueve esas instancias por la pantalla mientras cambia su tamaño, color, rotación y velocidad.

La mayor parte de este código simplemente configura CCParticleRain y le dice cómo debe comportarse. Los sistemas de partículas son muy flexibles y admite una increíble variedad de propiedades de configuración. Estas propiedades no están bien documentadas; Encontré la mayoría de ellos buscando en el código fuente de Cocos2D.

Los sistemas de partículas logran un aspecto natural al agregarles variabilidad aleatoria. Controlas el rango de la aleatoriedad con var propiedades. Por ejemplo, queremos que las estrellas comiencen entre 20 y 50 veces su tamaño normal, por lo que especificamos un startSize propiedad de 50.0f y un startSizeVar propiedad de 20.0f. Esto significa que cada una de las estrellas comenzará en algún lugar entre estos dos valores.

Crea tus propias animaciones

Ahora que ha visto algunos de los conceptos básicos en las animaciones de Cocos2D, puede crear las suyas propias. Un lugar fácil para comenzar es cambiar Seven Bridges. Sólo descargar el código fuente y empezar a ajustarlo.

Agrega una animación parpadeante para que el personaje del jugador parpadee mientras se mueve. Echa un vistazo a [PlayerNode](https://github.com/zgrossbart/bridges/blob/master/bridges2/PlayerNode.mm) para ver la secuencia para mover al jugador por la pantalla. Juega con el emisor de partículas para cambiar la forma en que funcionan las estrellas.

En este artículo, hemos revisado las animaciones programáticas en los juegos, pero Cocos2D también admite animaciones basadas en sprites. Estas animaciones reproducen una serie de imágenes para crear la ilusión de movimiento, algo así como un libro animado. Seven Bridges usa ese estilo de animación cuando mueve al jugador por la pantalla.

Animación de movimiento del jugador

Ray Wenderlich tiene un increíble tutorial sobre animación basada en sprites, titulado «Cómo usar animaciones y hojas de sprites en Cocos2D. » El artículo es excelente, pero menciona un producto llamado Zwoptex, y lo recomiendo encarecidamente. TexturePacker en lugar de.

Deja un comentario