En este artículo finalizaremos el tema sobre el motor de física 2D, Chipmunk. Hasta el momento hemos visto los conceptos básicos y elementos dinámicos presentes en las simulaciones. En este último revisaremos los elementos estáticos y la implementación del acelerómetro con nuestra aplicación. Desde ya hago extensiva la invitación para continuar explorando la documentación disponible y seguir probando el desempeño de las simulaciones en los dispositivos móviles (iPhone / iPod Touch/ iPad) para lograr una óptima implementación del motor de física 2D.

Conceptos

Antes de implementar los elementos estáticos en nuestra aplicación es importante recordar los tipos de Shapes que existen en Chipmunk y aclarar uno de ellos:

  • Circular: Genera una circunferencia para el cuerpo rígido referenciado cpCircleShapeNew(cpBody * body, cpFloat radius, cpVect offset)
  • Segmentado: Genera una forma lineal entre los puntos a y b cpSegmentShapeNew(cpBody * body, cpVect a, cpVect b, cpFloat radius)
  • Poligonal: Genera un polígono Convexo definido previamente por medio de sus vértices. En Chipmunk no se pueden modelar polígonos Concavos, para esos casos se debe utilizar Segment cpPolyShapeNew(cpBody * body, int numVerts, cpVect * verts, cpVect offset).

Finalizando la implementación en Xcode

Prosigamos con el proyecto creado para estos menesteres en el artículo anterior:

1. Definir Body y Shape de un objeto estático lineal en la función “(void)configurarChipmunk”

- (void)configurarChipmunk {

// Inicia el motor de fisica 2D Chipmunk

cpInitChipmunk();

// Crea un nuevo Space

space = cpSpaceNew();

// Define la dirección y magnitud de la gravedad en el Space

space->gravity = cpv(0, -100);

// Implementa el NSTimer encargado de realizar las animaciones

[NSTimer scheduledTimerWithTimeInterval:1.0f/60.0f target:self selector:@selector(delta:) userInfo:nil repeats:YES];

// Crea un Body con masa 50 y momento INFINITY

cpBody *esferaBody = cpBodyNew(50.0f, INFINITY);

// Establece posición inicial

esferaBody->p = cpv(160, 250);

// Agrega el Body al Space

cpSpaceAddBody(space, esferaBody);

// Crea un Shape tipo Circle con radio 15 asociado al Body "esferaBody"

cpShape *esferaShape = cpCircleShapeNew(esferaBody, 15.0f, cpvzero);

esferaShape->e = 0.5f; // Elasticidad

esferaShape->u = 0.8f; // Fricción

esferaShape->data = esfera; // Asocia Shape con UIImageView

esferaShape->collision_type = 1; // Las colisiones son agrupadas por tipo

// Agrega el Shape al Space

cpSpaceAddShape(space, esferaShape);

// ==============================

// Implementación Objeto Estático

// ==============================

// Crea un Body con masa y momento INFINITY

barraBody = cpBodyNew(INFINITY, INFINITY);

// Establece la posición inicial

barraBody->p = cpv(160,120);

// El Body de los objetos estáticos no debe agregarse al Space

// si quieres saber que pasa, agregalo 😉

// Crea un Shape tipo Segment asociado al Body barraBody

barraShape = cpSegmentShapeNew(barraBody, cpv(-105, -3), cpv(105, -3), 10.0);

barraShape->e = 0.7f; // Elasticidad

barraShape->u = 0.4f; // Fricción

barraShape->data = barra; // Asocia Shape con UIImageView

barraShape->collision_type = 0; // Se agrupa en un tipo de colisión diferente a "esferaShape"

// Agrega el Shape al Space
cpSpaceAddShape(space, barraShape);
}

2. Agregar “<UIAccelerometerDelegate>” en “ViewController.h”

#import <UIKit/UIKit.h>

#import "chipmunk.h"

@interface ViewController : UIViewController <UIAccelerometerDelegate>{

UIImageView *barra;

UIImageView *esfera;

cpSpace *space;

cpBody *barraBody;

cpShape *barraShape;

}

- (void)configurarChipmunk;

- (void)delta:(NSTimer *)timer;

void updateShape(void *ptr, void* unused);

@end

3. Definir la función que implementa el acelerómetro

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

// Modifica el ángulo de la Barra con relación a la inclinación del dispositivo

cpBodySetAngle(barraBody, M_PI * (acceleration.x * 0.6f) );

// Notifica a Chipmunk el movimiento de un Objeto Estático

cpSpaceRehashStatic(space);

// Actualiza el Shape de la Barra (Objeto Estático)

[(UIView *)barraShape->data setTransform:

CGAffineTransformMakeRotation(-barraShape->body->a)];

}

4. Inicializamos el acelerómetro en la función “(void)viewDidLoad”

- (void)viewDidLoad {

[super viewDidLoad];

barra = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"barra.png"]];

barra.center = CGPointMake(160, 350);

esfera = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"esfera.png"]];

esfera.center = CGPointMake(160, 230);

[self.view addSubview:barra];

[self.view addSubview:esfera];

[self.view setBackgroundColor:[UIColor whiteColor]];

[self configurarChipmunk];

// Inicia el acelerómetro

[[UIAccelerometer sharedAccelerometer] setUpdateInterval:(1.0 / 60)];

[[UIAccelerometer sharedAccelerometer] setDelegate:self];

}

5. Compilar y ejecutar

Si hemos hecho todo bien al final obtendremos un objeto circular que se sostiene con un madero el cual gira con el movimiento del dispositivo. Se puede seguir probando con distintos valores de masa, fricción, elasticidad, gravedad, entro otros para conocer un poco más el comportamiento de los objetos dentro del espacio creado.

De esta manera terminan los artículos sobre Chipmunk, esperando que los conceptos tratados sirvan para continuar aprendiendo sobre esta herramienta y así mejorar el desarrollo de nuestras aplicaciones.

Repositorio en GitHub : MDW-Guia-iOS12-Chipmunk3