viernes, 17 de agosto de 2012

ChipMunk - Librería de física 2D - Videojuegos para Iphone - Definiendo el cuerpo y la forma para el piso (Parte 6)

El piso necesita un cuerpo y una forma mas compleja. Crear el cuerpo es sencillo y solo tiene 2 detalles: su masa no importa y no la vamos a agregar a nuestro espacio. Esto puede sorprenderderlos pero si piensan por segundo se daran cuenta que el piso es estatico y por lo tanto no es necesario agregarle gravedad o un espacio. Por la misma razón configurar la masa estaría bien pero no tendría ningún efecto. Entonces, agregamos este código al final método setupChipmunk (También lo podemos agregar antes de la creación del cuerpo y forma de la pelota sin efectos negativos).
// Creamos el cuerpo del piso y le seteamos posición
  
cpBody *floorBody = cpBodyNew(INFINITY, INFINITY);  
  
floorBody->p = cpv(160, 480-350);

Entonces, ahora que tenemos el cuerpo necesitamos las formas. Hay muchas maneras de adjuntar la imagen, como comente en la sección de conceptos se puede agregar varias formas al cuerpo. En nuestro caso podemos crear varias lineas o definir un polígono. Realizaremos lo último porque es menos confuso si es que son nuevos en C. Los polígonos son poderosos pero tienen algunas restricciones en Chipmunk que deberían entender para poder aplicarlo de manera correcta. Lo primero que deben saber es que deberas proveer todos los vertices en el sentido de las agujas del reloj. Otra cosa que deben saber acerca de los polígonos en Chipmunk es que definen una forma convexa. Un poligono convexo es aquel donde la linea entre 2 puntos dentro de la forma sigue dentro de la forma.




Pueden buscar más información en Wikipedia o en este sitio.
// Definiendo los vertices de la forma
      
    cpVect verts1[] = { cpv(0.0, 0.0), cpv(50.0, 0.0), cpv(45.0, -15.0), cpv(0.0, -15.0) };  
      
    cpVect verts2[] = { cpv(50.0, 0.0), cpv(116.0, -66.0), cpv(110.0, -81.0), cpv(45.0, -15.0) };  
      
    cpVect verts3[] = { cpv(116.0, -66.0), cpv(204.0, -66.0), cpv(210.0, -81.0), cpv(110.0, -81.0) };  
      
    cpVect verts4[] = { cpv(204.0, -66.0), cpv(270.0, 0.0), cpv(275.0, -15.0), cpv(210.0, -81.0) };  
      
    cpVect verts5[] = { cpv(270.0, 0.0), cpv(320.0, 0.0), cpv(320.0, -15.0), cpv(275.0, -15.0) };  
Esto significa que si estas utilizando las imágenes que yo otorgué no seremos capaces de definir correctamente el piso solo con una forma. Para definirlo correctamente debemos utilizar 5 formas poligonales, vamos a definirlas.
    // Creando todas las formas 
      
    cpShape *floorShape = cpPolyShapeNew(floorBody, 4, verts1, cpv(-320.0f / 2, 81.0f / 2));  
      
    floorShape->e = 0.5; floorShape->u = 0.1; floorShape->collision_type = 0;  
      
    floorShape->data = floor;  
      
    cpSpaceAddStaticShape(space, floorShape);  
      
    floorShape = cpPolyShapeNew(floorBody, 4, verts2, cpv(-320.0f / 2, 81.0f / 2));  
      
    floorShape->e = 0.5; floorShape->u = 0.1; floorShape->collision_type = 0;  
      
    floorShape->data = floor;  
      
    cpSpaceAddStaticShape(space, floorShape);  
      
    floorShape = cpPolyShapeNew(floorBody, 4, verts3, cpv(-320.0f / 2, 81.0f / 2));  
      
    floorShape->e = 0.5; floorShape->u = 0.1; floorShape->collision_type = 0;  
      
    floorShape->data = floor;  
      
    cpSpaceAddStaticShape(space, floorShape);  
      
    floorShape = cpPolyShapeNew(floorBody, 4, verts4, cpv(-320.0f / 2, 81.0f / 2));  
      
    floorShape->e = 0.5; floorShape->u = 0.1; floorShape->collision_type = 0;  
      
    floorShape->data = floor;  
      
    cpSpaceAddStaticShape(space, floorShape);  
      
    floorShape = cpPolyShapeNew(floorBody, 4, verts5, cpv(-320.0f / 2, 81.0f / 2));  
      
    floorShape->e = 0.5; floorShape->u = 0.1; floorShape->collision_type = 0;  
      
    floorShape->data = floor;  
      
    cpSpaceAddStaticShape(space, floorShape);  
Este código debería ser facil de entender ahora. Crea 5 formas, todas adjuntadas al cuerpo del piso y después se setean algunas propiedades. Hay dos diferencias menores entre la forma en que la forma del piso es definida y las definicion anterior de la pelota. La primer diferencia es el ajuste de la fricción desde 0.8 a 0.1, sin esta fricción entre el piso y la pelota. La segunda diferencia es la manera en que las formas son agregadas, se utiliza cpSpaceAddStaticShape en vez de cpSpaceAddSpace para que la forma no se mueva. Chipmunk usa esto para optimizar los calculos en cada paso y reducir uso de CPU. Si ejecutamos el proyecto la pelota va a caer y en vez de pasar a través del piso va a golpear con el mismo y frenarse. Esto es un buen indicio de que las dos formas estan interactuando correctamente, no nos da la mejor demostración de lo que aprendimos. Busquemos el código donde creamos y configuaramos el cuerpo de la pelota y cambiemos la posición del vector X de 160 a 60.
ballBody->p = cpv(60, 250); 
si ejecutamos otra vez el demo vamos a ver que la pelota comienza a deslizarce un poco más a la izquierda cayendo con la inclinación y haciendo un movimiento muy realístico a través del piso.

No hay comentarios: