jueves, 17 de mayo de 2012

La capa de un Super Héroe. Efecto bandera / Flag Effect


Recientemente ha salido al mercado el último juego desarrollado por Bluelephant,  cuyo personaje está compuesto por varias imágenes para lograr una fluidez total en sus animaciones. Esto son las llamadas "Animaciones procedurales" las cuales no dependen de un grafista para diseñar la manera en la que corre un personaje, o vuela. De esta manera podemos hacer que cualquier cosa con 2 piernas, y dos brazos, corra de manera natural.

Pero el punto fuerte de esta entrada no son las animaciones procedurales, sino la animación de la capa en sí, ya que es una simple imagen, pero usando llamadas openGL sobre cocos2D para lograr el efecto ondulante.

En este tutorial vamos a enseñar como hacer una capa ondulante para poder añadir a cualquier héroe, y ya vuestra imaginación podrá también descubrir como hacer el efecto de una bandera, el cual es más simple (en lo que a cálculo matemático en el código se refiere)

Este es el efecto que conseguiremos:
Antes de nada, recordar que Cocos2D tiene este mismo efecto, pero puesto que se puede aplicar a todas los sprites que estén como child dentro del nodo, su velocidad es NEFASTA. Tirando los FPS del juego por debajo de los 30fps tan pronto como se añaden dos o tres pequeños sprites a la escena. Por lo tanto, desaconsejo totalmente el uso de esa función en cocos2D y usar esta, para mejorar la velocidad global NOTABLEMENTE en el juego.

Para empezar crearemos una clase SuperCapa.m con su correspondiente cabecera, SuperCapa.h.

#import 
#import "cocos2d.h"

@interface SuperCapa : CCSprite {
    int LADOS;
    float t;
    float velocidad;
    float fps;
    CGPoint texturePos[30];
}
-(void) setVelocidad:(float) v DT:(ccTime) fp;
@end


Tenemos un método para poder controlar la velocidad a la que se mueve y la frecuencia de actualización de la pantalla (los parámetros v y fp) por otro lado tenemos como variables de instancia LADOS que definirá como de "bien hecha" está la capa, es decir, por cuantos segmentos estará formada, t, que será el momento en el que se encuentra la animación y las posiciones de la textura que vamos a mover.

Ahora vamos a ver la clase Super.m

#import "SuperCapa.h"


@implementation SuperCapa

-(id) init{
    if (self = [super init]) {
        LADOS = 9;
        int c = 0;
        for (int i = 0; i<LADOS; i++) {
            for (int j = 0; j<2; j++) {
                texturePos[c] = ccp(((float) i/(float)(LADOS-1)),1-(float)j);
                c = c + 1;
            }
        }
        NSString* capa = @"Nombre-de-tu-capa.png" // DEBE DE SER CUADRADA Y POTENCIA DE 2!
        [self setTexture:[[CCTextureCache sharedTextureCache] addImage:capa]];
        
        t = 0;
        
    }
    return self;
}

-(void) dealloc{
    [super dealloc];
}

-(void) setVelocidad:(float) v DT:(ccTime) fp{
    fps = fp;
    velocidad = v;
}

-( void )draw{
 CGPoint segmentPos[LADOS*2];
    float x,y;
    int c = 0;
    t = t + (fps*velocidad);
    if (t>(M_PI*2))
        t = t - (M_PI*2);
    float porcentaje = 0;
    for (int i = 0; i<LADOS; i++) {
        for (int j = 0; j<2; j++) {
            porcentaje = MAX(0,((float)(LADOS- (i+1))/LADOS));
            x = i*(128/LADOS);
            y = j*128 + cosf(t + (i*(2*M_PI/LADOS))) * porcentaje * 25;
            segmentPos[c] = ccp(x,y);
            segmentPos[c] = ccpAdd(ccp(-115,-64), segmentPos[c]); //My anchor point
            c = c + 1;
        }
    }
    glEnable( GL_TEXTURE_2D );
    glBindTexture( GL_TEXTURE_2D, [self texture].name ); 
    glDisableClientState( GL_COLOR_ARRAY);
    glTexCoordPointer( 2, GL_FLOAT, 0, texturePos );
    glVertexPointer( 2, GL_FLOAT, 0, segmentPos );
    glDrawArrays( GL_TRIANGLE_STRIP, 0, LADOS*2);
    glEnableClientState( GL_COLOR_ARRAY ) ;
}
@end


La mágia está en el método draw, que es el método que estamos sobre escribiendo de la clase CCSprite, para poder animar nuestra capa a nuestro antojo. Como veis no tiene mucho misterio y el resultado es simple y optimizado.

1 comentario:

  1. Hola Daniel
    Enhorabuena por tu blog, me ayuda mucho.
    Estoy empezando en el tema de Cocos2D y bueno ademas de leer mucho en la red pues pensaba hacer algun curso...he visto este:
    http://www.cocoaosx.com/cursos/curso-cocos2d-basico/

    ¿Como lo ves?¿Algun consejo mas?
    GRACIAS

    ResponderEliminar