Programación de Juegos para Android

Programación de Juegos para Android 28: Cómo controlar colisiones

42 videos

238 minutos

Para aplicar esas colisiones, tenemos en Box2D lo que se conoce como Contactos. Cada vez que ocurre una colisión o que dos fixtures chocan de algún modo o intentan ocupar la misma región del espacio, se produce un contacto y podemos ser notificados de ello. Para ello World trae un método llamado setContactListener, con el que podemos asociar un ContactListener a nuestro mundo, que es el listener asociado para escuchar cuándo se producen esos contactos.

Por lo que yo simplemente voy a hacer un setContactListener(new ContactListener()) para poder definir uno rápido, aunque esto se puede hacer de mejor forma. Como veis, ContactListener implementa varios métodos. Podemos utilizar beginContact para detectar cuándo hemos comenzado una colisión, y endContact para detectar cuando hemos terminado una colisión. preSolve y postSolve se ejecutan cuando las físicas están procesando un contacto y con ello podremos

hacer físicas que utilicen parámetros especiales, pero en nuestro caso no lo vamos a usar aún. Vamos a aprovechar sólo BeginContact y EndContact. Cada vez que el jugador choque de alguna forma con el suelo, se va a producir un contacto entre dos Fixtures, a los que podemos acceder mediante los métodos getFixtureA y getFixtureB de Contact. Aquí es donde vienen los problemas, porque no podemos saber inicialmente dónde está el Body,

si es la fixture A o la fixture B, por lo que todo lo que hagamos aquí, y todas las decisiones que tomemos de detectar cuando el body choca con el suelo, debemos considerarlo tanto si A == body, B == suelo, como cuando A == suelo, B == body, así que tendremos que escribir lo mismo un par de veces. No es tan limpio como podría ser. Por ejemplo, puedo obtener la fixture A del contacto usando contact.getFixtureA(), y la fixture B usando contact.getFixtureB().

Y ahora puedo detectar si mi fixture corresponde con la de Body o no. Y aquí es donde vienen los problemas porque… ¿cómo lo hago? Inicialmente yo sólo conozco la propia Fixture. Lo que tendría que hacer es determinar, por ejemplo, si fixtureA es la misma variable que minijoeFixture y fixtureB la misma que sueloFixture, aunque ya os enseñaré cómo podemos hacer esto de otras maneras mediante UserDatas. Por ahora, si la Fixture A

es la de Minijoe, y la Fixture B es la del suelo, puedo pedirle a nuestro cuerpo que salte. Pensaréis que es facil, llamando a saltar. Yo también pensé que sería así, pero resulta que no. No puedes hacer que se inicie un salto dentro de un ContactListener, porque resulta que los saltos exigen que el motor no esté trabajando, y durante un contacto Box2D estará trabajando en cosas así que esto no funcionará. En su lugar, lo que deberemos hacer es pedirle a Box2D que en un momento

que esté libre, salte. Y esto se traduce en recordar en nuestro juego que se debe iniciar un salto. Y esto quiere decir, que básicamente debo crear una variable booleana que tenga como valor haColisionado. Yo puedo aquí hacer que cuando se produzca una colisión valga verdadero. Y como os he dicho antes, debido a que necesito que tanto mi fixture A como la fixture B se asocie a un cuerpo u otro, debo hacer esto dos veces. Por ejemplo, si fixtureA es la de suelo

en vez de ser la de Joe, debo hacer lo mismo. Poner haColisionado a true. Y una vez que estamos fuera de nuestro gestor de colisiones ya puedo hacer que, si hemos tocado o si ha colisionado, saltemos, y luego además que se ponga haColisionado a falso para evitar que por algun motivo pueda saltar varias veces. De este modo, ahora cada vez que se produzca una colisión, va a saltar otra vez. Como digo, no se pueden hacer saltos dentro del mismo gestor de colisiones,

porque se hace cuando está trabajando. Así que no queda otra que poner un flag para que lo haga más adelante, en el caso por ejemplo de haColisionado. Esto se suele hacer con entidades, como podría ser una entidad seria como BodyEntity o PlayerEntity, con propiedades como estaSaltando, debeSaltar, enElAire, que sean más flexibles de controlar. En mi caso como esto es tan cómodo de acceder a todas las variables aún no lo estoy haciendo,

pero tranquilos que cuando incorporemos Scene2D a esta pantalla, lo moveremos para que quede más limpio, evidentemente.

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!!!!!