Bienvenidos sean a este post, hoy nos centraremos en el ultimo detalle de nuestro juego como son las colisiones entre nuestro objetos.
Para este tema vamos a modificar principalmente la clase FisicasEngine donde cambiaremos un metodo y agregaremos uno nuevo, el metodo que vamos a modificar es actualizar donde cambiaremos esta linea:
return false;
Por la siguiente linea:
return detectarColisiones(ge, objetos, se, sp);
En lugar de devolver un false ahora devolveremos una funcion, nuestra siguiente paso sera agregar esta funcion dentro de la clase:
private boolean detectarColisiones(
GameState mGameState,
ArrayList<GameObjeto> objetos,
SoundEngine se,
SistemaParticula sp){
boolean impactoJugador = false;
for(GameObjeto go1 : objetos){
if (go1.chekaActivo()){
for(GameObjeto go2 : objetos){
if (go2.chekaActivo()){
if (RectF.intersects(
go1.getTransformar().getColision(),
go2.getTransformar().getColision())){
switch(go1.getTag() + " con " + go2.getTag()){
}
}
}
}
}
}
return impactoJugador;
}
Como su nombre lo indica este sera el metodo encargado de detectar las colisiones, en este caso recibira todos los valores que enviamos en la modificacion anterior, en su bloque primero crearemos un booleano que llamaremos impactoJugador, luego usaremos dos for mejorados anidados, primero crearemos un bucle for mejorado para pasar por todos los objetos y lo almacenaremos en go1, usaremos un condicional que verifica si el objeto en go1 esta activo, en caso de ser cierto luego crearemos exactamente uno igual pero lo obtenido lo almacenaremos en go2, volveremos a verificar si esta activo el objeto pero en este caso usaremos a go2 y en caso de ser verdadero usaremos a intersects de RectF donde pasarems los dos objetos, obtenemos el objeto transformado y usamos a getColision para verificar si interceptan, en caso de ser verdadero usaremos un switch donde concatenamos el valor de tag del objeto 1 con el tag del objeto 2 y la palabra «con» pero por ahora lo dejamos vacio porque para nuestro siguiente paso sera completar dicho switch porque es algo complejo de explicar, veamos como debe quedar:
switch(go1.getTag() + " con " + go2.getTag()){
case "jugador con laser alien":
impactoJugador = true;
mGameState.perderVida(se);
break;
case "jugador con alien":
impactoJugador = true;
mGameState.perderVida(se);
break;
case "laser jugador con alien":
mGameState.incrementaPuntaje();
sp.emitirParticulas(new PointF(
go2.getTransformar().getPosicion().x,
go2.getTransformar().getPosicion().y)
);
go2.setInactivo();
go2.generar(objetos.get(Nivel.INDICE_JUGADOR)
.getTransformar());
go1.setInactivo();
se.repAlienExplotar();
break;
default:
break;
}
En este caso el switch tomara la concatenacion del tag de los objetos unidas con la palabra «con», vamos a ver un ejemplo de case:
case "jugador con laser alien":
impactoJugador = true;
mGameState.perderVida(se);
break;
En este caso vemos cuando el jugador es impactado con un laser enemigo, por lo tanto setea a impactoJugador como verdadero y llama a perderVida para disminuir la cantidad en GameState, el siguiente es similar a este pero contempla la situacion de cuando alguno de los aliens choca contra nuestra nave, las instrucciones son las mismas, en el ultimo case es cuando nuestro laser, como todos los aliens comparten el mismo tag involucra a todos, si se cumple primero incrementa el puntaje, luego genera la explosion con los datos del go2, luego setea a go2 como inactivo, despues genera un nuevo objeto con go2, tambien seteamos a inactivo como go1 (es decir que desaparece el laser), y por ultimo reproducimos el sonido de la explosion del alien, veamos como quedo nuestro codigo final de este metodo:
private boolean detectarColisiones(
GameState mGameState,
ArrayList<GameObjeto> objetos,
SoundEngine se,
SistemaParticula sp){
boolean impactoJugador = false;
for(GameObjeto go1 : objetos){
if (go1.chekaActivo()){
for(GameObjeto go2 : objetos){
if (go2.chekaActivo()){
if (RectF.intersects(
go1.getTransformar().getColision(),
go2.getTransformar().getColision())){
switch(go1.getTag() + " con " + go2.getTag()){
case "jugador con laser alien":
impactoJugador = true;
mGameState.perderVida(se);
break;
case "jugador con alien":
impactoJugador = true;
mGameState.perderVida(se);
break;
case "jugador laser con alien":
mGameState.incrementaPuntaje();
sp.emitirParticulas(new PointF(
go2.getTransformar().getPosicion().x,
go2.getTransformar().getPosicion().y)
);
go2.setInactivo();
go2.generar(objetos.get(Nivel.INDICE_JUGADOR)
.getTransformar());
go1.setInactivo();
se.repAlienExplotar();
break;
default:
break;
}
}
}
}
}
}
return impactoJugador;
}
Con esto ya tenemos nuestro juego completo, podemos probarlo como se ve en el siguiente video
En el video podemos ver todos las conductas de nuestro juego, inclusive pueden ver un record de una prueba del juego, ya sea desde las explosiones de nuestro enemigo, nuestras perdidas de vida, el final del juego y el movimiento del fondo de pantalla, con esto hemos concluido nuestro quinto juego.
En resumen, hoy hemos visto otra forma de detectar las colisiones, en forma general es muy similar porque seguimos usando a intersects de RectF pero aqui pudimos lograr un objetivo fundamental como es tener un solo metodo de deteccion de colisiones sin importar la cantidad de objetos, tambien hemos visto una forma interesante de su deteccion, espero les haya gustado sigueme en tumblr, Twitter o Facebook para recibir una notificacion cada vez que subo un nuevo post en este blog, nos vemos en el proximo post.
Tengo un Patreon donde podes acceder de manera exclusiva a material para este blog antes de ser publicado, sigue los pasos del link para saber como.


Donación
Es para mantenimento del sitio, gracias!
$1.00
