Programación de Juegos para Android

Programación de Juegos para Android 19: Detectar Colisiones

42 videos

238 minutos

Hablemos de colisiones porque evidentemente me interesa que mi jugador sepa que ha sido golpeado por uno de los pinchos. Lo primero que voy a hacer es fijarme en una cosa que tiene la clase Stage para obtener los límites de los objetos, y es el modo de depuración. Os voy a enseñar cómo entrar en el modo de depuración para poder ver con detalle los actores que tenemos en el escenario, y entenderéis por qué. Primero llamo al método setDebugAll para indicarle que cuando se ejecute nos

muestre los bordes de los objetos. Si le pasamos true, al borde de cada objeto aparecerá una línea que bordeará el actor para que sepamos que son sus límites. Para que funcione hace falta darle a los actores unos tamaños, y no lo hemos hecho, sólo he dado posiciones. Lo primero que voy a hacer es darle las dimensiones al actor. Y eso lo puedo hacer directamente desde el constructor, porque las texturas y las TextureRegions tienen métodos para obtener

el ancho y el alto de la textura, y eso me viene perfecto para decirle a mi actor: “oye, tu nuevo tamaño (con setSize) es pinchos.getRegionWidth(), para obtener el ancho de la región, y pinchos.getRegionHeight(), para obtener el alto”. De este modo ya conocemos cuánto mide el ActorPinchos: lo que mida la textura. Con ActorJugador pasa lo mismo. Este os lo sabéis porque lo hice en los primeros vídeos: getWidth() y getHeight().

Esto combinado con esto otro, porque necesitamos sus dimensiones, nos permite obtener directamente este borde verde que vais a ver ahora alrededor de nuestro personaje. Con esto más o menos lo que podemos hacer es determinar cuáles son los límites, y nos va a ayudar a ver cómo podemos hacer que se detecte cuando ha habido una colisión. Voy a volver a mi Skitch para entender cómo voy a gestionar las colisiones. Hay mejores formas de gestionarlas, y próximamente

vamos a ver cómo podemos empezar a introducir Box2D, una tecnología muy interesante que nos va a permitir, agregar físicas realistas al juego, y detectar de mejor forma cómo se obtiene una colisión. Por el momento vamos a estudiar cómo obtener un algoritmo sencillo que abra boca para más adelante. En este momento nuestro actor lo podemos reducir a un cuadrado. Todos los actores, de hecho. Tenemos un jugador y tenemos un pincho.

Lo que nos interesa es detectar cuándo ha ocurrido esto: es decir, cuándo los pinchos han chocado con el actor. Aparentemente hay una forma simple de ver cuándo hemos chocado; y es que aquí tenemos esta línea vertical, que sería la que se corresponde con la posición X del jugador. Cuando decimos setX() lo que indicamos es donde se pone esta línea porque el origen de coordenadas lo indicamos en la parte izquierda. Conocemos lo que mide de ancho el actor,

por lo que es sencillo determinar el borde derecho haciendo una suma de X + WIDTH. De forma parecida, podemos obtener el borde izquierdo de nuestros pinchos utilizando X en el caso de los pinchos. Cuando ocurre una colisión, ocurre una cosa interesante: las colisiones ocurren porque el borde izquierdo de nuestro ActorPinchos está más a la izquierda, es decir, su X vale menos, que el valor de X + Width de pinchos. Si hacemos una comparativa entre pinchos.x

y (jugador.x + jugador.width), lo que ocurre es que is hay una colisión es porque el primero es más pequeño que el segundo. Si esta condición es verdadera, hay una colisión, porque los pinchos están literalmente dentro del jugador. Esta es la primera estrategia a seguir para detectar colisiones. Uso en el método render antes de llamar a draw() una llamada al método llamado comprobarColisiones() que voy a crear ahora. Existe cierta discrepancia frente a

cuándo hacer la actualización y el dibujado. No os dejéis engañar: siempre actualizad antes de dibujar. Porque si no, si lo hacéis al revés, es decir, metéis el draw() en primer lugar, tendréis un problema, porque lo que las colisiones se comprobarán después de hacer el act(), y el act() no será lo que el jugador esté viendo. Como el draw() se hizo antes, el jugador no lo percibe. Y en juegos que tienen mucho movimiento esto es un problema,

así que primero haced las actualizaciones y las comprobaciones y por último cuando todo esté listo dibujadlo. Sobre todo con Box2D, esto va a ser muy importante. Lo último que voy a hacer es escribir el método comprobarColisiones() para comprobar lo que os he dicho. Si el borde derecho de mi jugador es mayor que el borde izquierdo de mis pinchos, es porque ha habido una colisión. Buen momento para matar al jugador, básicamente. Le puedo poner una condición

que sea vivo, y mediante un getter y un setter puedo modificar o comprobar si mi jugador está vivo o no. Ahora lo que hago, por último es, que si el jugador está vivo y ha colisionado, se imprima colisión. Quiero hacer esto, porque si no, mientras los pinchos se sigan moviendo va a aparecer decenas de veces el mensaje de colisión. Para que termine de estar bien queda que el setAlive se ponga a false para que no vuelva a valer verdadero. Se trata de evitar que se imprima

muchas veces el mensaje colisión. Esta es una forma un poco burda y sucia pero permite comprobar mediante un modelo matemático… — bueno. Voy a ver por qué no funciona. Puede que porque haya olvidado poner esto. Sí, cierto. Perdonad este detalle: cuando empiezas la partida, la empiezas vivo. Ahora sí. Decía que por modelos geométricos básicos como los de rectángulos podemos comprobar cuándo ha habido una colisión. Esta técnica se llama bounding boxes.

No es la mejor tecnología para comprobar colisiones pero en juegos básicos 2D lo es. No obstante, con Box2D tendremos un mejor sistema para integrar físicas.

Si quieres enterarte de los nuevos cursos, suscríbete. No habrá spam, prometido :)

Sobre el autor

foto de jotajotavm
José Javier Villena

jotajota pa los amigos y jota pa los de más cnfianza.

Bio Seria: Analista-Programador en diferentes lenguajes. Tutor PREMIUM de reconocidas plataformas de nivel mundial como CodigoFacilito. Redactor de artículos para Cristalab. Mi canal de YouTube está patrocinado por la editorial ANAYA y LaTostadora. Me gusta explicar con detalle y poner varios ejemplos para que no queden dudas.

Bio Molona: Me presento :) soy informatico, ni frostis d hardware pero muy muxo de programacion, friki a medias o del to segun el dia. Me gusta programar, muxo. Manejo varios lenguajes y tdo lo ke sepa lo comparto x amor al arte. Este no es mi trabjo pero lo ago mejor y con +ganas y calidad que si lo fuera, x eso mismo, xq para mi es divertido. Solo spero al menos algo de agradecimientO!! ;)

Dios, qe gusto haber escrito este parrafo cm me a dao la gana sin pensar en ortografia ni tildes ni historias!!!!!