martes, 2 de agosto de 2011

Acelerómetro y Cocos2D

Hoy enseñaré como usar el acelerómetro y además, a elegir una imagen de un sprite, acorde con el ángulo del iPhone.

Para ello, necesitaremos esta flecha que he diseñado yo mismo (para vuestro uso y tutorial)
Descarga flecha animada / Download animated arrow

será algo tal que así:
Cómo veis es una imagen parecida a la que subí anteriormente, por lo que el ZIP de Megaupload contiene las imágenes en HD y SD así como los archivos correspondientes "plist"





Y este será el resultado final del tutorial:



Empecemos con el tutorial. Primero bajad la imagen mencionada y a continuación, cread un proyecto Cocos2D.

Una vez creado, arrastrar la carpeta que se encuentra dentro del zip a la carpeta resources de tu proyecto. Cuando te pregunte "Copy items into destination group's folder (if needed)" marca el casillero.

Si todo ha salido bien, ahora tendremos un HelloWorldLayer.m. De esta clase no necesitamos el init tal y como está, así que lo eliminamos y lo reemplazamos por el siguiente.
// on "init" you need to initialize your instance
-(id) init
{
 // always call "super" init
 // Apple recommends to re-assign "self" with the "super" return value
 if( (self=[super init])) {  
  //Habilitamos el uso del acelerómetro
        [[CCSpriteFrameCache sharedSpriteFrameCache] addSpriteFramesWithFile:[[NSBundle mainBundle] pathForResource:@"Flecha" ofType:@"plist"]]; /Carga del fichero plist, que contiene información relativa a la posición de los sprites
        flecha = [CCSprite spriteWithSpriteFrameName:@"Flecha090.png"];
        flecha.position = ccp(240,160);
        self.isAccelerometerEnabled = YES;
        
        [self addChild:flecha];
 }
 return self;
}

- (void)accelerometer:(UIAccelerometer*)accelerometer didAccelerate:(UIAcceleration*)acceleration{}

Si os fijáis he añadido aquí la carga del plist (al cargar el plist, automáticamente se cargan todos los sprites del PNG, clasificados por nombre con el siguiente formato: FlechaXXX.png), he añadido además un procedimiento "accelerometer". Aquí en este procedimiento escribiremos la lógica para rotar el sprite de la flecha, así como asignar la imagen que debemos mostrar.

Como es de esperar, este procedimiento es el que maneja los eventos del acelerómetro. Cómo queremos añadir movimiento a nuestro sprite, en relación a la inclinación del iPhone, debemos realizar aquí la mayor parte (o toda) de la lógica del código.

Así que... Vamos a rellenar ese espacio vacío.
- (void)accelerometer:(UIAccelerometer*)accelerometer didAccelerate:(UIAcceleration*)acceleration{
    [flecha setRotation: (atan2f(acceleration.x, acceleration.y)*360.0f)/(2.0f*PI)];
    int imagen = [self normaliza:acceleration.z];
    if (imagen < 10){
        [flecha setDisplayFrame:[[CCSpriteFrameCache sharedSpriteFrameCache] spriteFrameByName:[NSString stringWithFormat:@"Flecha00%d.png",imagen]]];
    }else if(imagen<100){
        [flecha setDisplayFrame:[[CCSpriteFrameCache sharedSpriteFrameCache] spriteFrameByName:[NSString stringWithFormat:@"Flecha0%d.png",imagen]]];
    }else{
        [flecha setDisplayFrame:[[CCSpriteFrameCache sharedSpriteFrameCache] spriteFrameByName:[NSString stringWithFormat:@"Flecha%d.png",imagen]]];
    }
}
La función normalizar, no hace otra cosa que convertir la gravedad, en un ángulo (por así decirlo) y como sólo tenemos 180 imagenes (una imágen para cada grado) la función retorna un ángulo entre 180 y 1.
-(float) normaliza:(float) ang{
    int tmp = (ang + 1.0f) * 90;
    tmp = MIN(180,tmp);
    tmp = MAX(1,tmp);
    return tmp;
}
Y por último, añadimos al header la siguiente línea
// When you import this file, you import all the cocos2d classes
#import "cocos2d.h"

// HelloWorldLayer
@interface HelloWorldLayer : CCLayer
{
    CCSprite * flecha; //Esta línea debemos añadir
}

// returns a CCScene that contains the HelloWorldLayer as the only child
+(CCScene *) scene;

@end

Y eso es todo por hoy. Seguiré mis labores y la creación de mi juego.

¡Que lo disfrutéis!

PD: Se puede mejorar usando filtros matemáticos para "suavizar" el movimiento de la flecha, pero eso ya lo dejo a vuestro cargo ;)

1 comentario:

  1. sería bueno, si tienes tiempo, nos mostraras como jodidos hacer los sprites, veo que es mucho trabajo xD, un saludo desde Tepic, México...

    ResponderEliminar