Capítulo 5 - Colisiones

En este capítulo veremos cómo crear un contact listener y cómo tratar los distintos tipos de colisiones que dividimos en capas en Tiled.

5.1 Set up

Comenzaremos por ver como inicializar la física del jugador y un contact listener

createPhysicsBodyFromPoints.cpp

Un contact listener tiene varios métodos: begin, pre-solve, post-solve, separate. De todos estos sólo necesitaremos el begin y el separate. El método begin se ejecuta al colisionar dos objetos, si se retorna false es como si la colisión no hubiese sucedido y el resto de métodos pre-solve, post-solve, separate no se ejecutan. El método separate se ejecuta cuando dos objetos que están colisionando se separa.

Como podemos ver la primera parte de este método, creamos el listener, añadimos las funciones y lo subscribimos para que escuche las colisiones. En el capítulo anterior se nombró el método setContactTestBitmask si no se establece esta mascara, el listener no será llamado.

Tras crear el listener, añadimos la física al jugador.

5.2 Diferenciando colisiones

La mayor parte del trabajo se realizará en el método begin veamos como implementa la clase player el suyo:

onContactBegin.cpp

Como vemos en el onContactBegin se llaman a varios métodos, vayamos por partes. El más simple de ellos es onContactWinningArea. Primero hay que verificar que se trata de una colisión entre la winning área y el jugador con el método auxiliar areThisTwoTypes, una vez se sabe que estos son los nodos que colisionan, se actúa en consecuencia, es decir si el jugador ha llegado a la winning zone, declaramos que el jugador ha ganado. De esta forma procedemos con el resto de tipos de colisiones, en el método onContactWall vemos como al colisionar el jugador con las paredes se le hace retroceder player->getPhysicsBody()->setVelocity(Point(-350, 500)).

A continuación presta atención a los métodos onContactEnemy y onContactTerrain

onContactEnemy.cpp

Después de obtener al jugador y al enemigo con el que colisiona, verificamos si el jugador está saltando, de ser así hacemos que el enemigo muera, si no es así, es el player el que muere y si colisiona con un enemigo ya muerto hacemos que la colisión no se tenga en cuenta haciendo return false.

onContactTerrain.cpp

Este método gestiona las colisiones con el terreno, como vemos, al colisionar con el terreno, hacemos que la gravedad deje de afectar al player, esto es porque Chipmunk en ocasiones lanzaba mi personaje por los aires sin sentido alguno y la única solución que encontré es desactivar la gravedad al calcular la colisión con el suelo, posteriormente en el onContactSeperate la gravedad vuelve a activarse.

En la calse enemy el proceso es identico sólo que únicamente tratamos las colisiones con el suelo. El resultado final es el siguiente:

juego

Recuerda comentar él código que pinta las líneas del suelo en el método visto en el capítulo 3 acerca de capas de objetos.


Capítulo anterior