Bienvenidos sean a este post, hoy agregaremos las acciones principales a nuestro primer proyecto.
Para este caso extenderemos un poco mas el uso del metodo onTouchEvent, si bien en este post agregamos las funciones getX y getY para obtener ambas coordenadas, para esta ocasion vamos a utilizar las siguientes funciones y constantes:
- getAction, nos devuelve cual accion fue realizada pero no de forma directa
- ACTION_MASK, variable que nos permite filtrar el valor devuelto por el metodo anterior
- ACTION_UP, variable usada para comparar si es la requerida por nosotros
- getX, devuelve la coordenada del punto flotante horizontal
- getY, devuelve la coordenada del punto flotante vertical
Para nuestra modificacion, cambiaremos a la funcion onTouchEvent de la siguiente manera:
@Override
public boolean onTouchEvent(MotionEvent evento)
{
horizTocado = (int)evento.getX();
vertTocado = (int)evento.getY();
if ((evento.getAction() &
MotionEvent.ACTION_MASK) == MotionEvent.ACTION_UP){
disparar(horizTocado,vertTocado);
}
Log.d("Depurando","En el onTouchEvent");
Log.d("Depurando","horizTocado: " + horizTocado);
Log.d("Depurando","vertTocado: " + vertTocado);
return true;
}
En este caso vamos a agregar un condicional donde verifica si pulsamos y levantamos el dedo de la pantalla, si es verdad llama a la funcion disparar pasando como argumentos las coordenadas de los ejes X e Y por medio de getX y getY respectivamente, si lo probamos nos devolvera un error pero antes de modificar disparo vamos a modificar las variables de ubicacion del submarino de la siguiente forma:
subHorPosicion = alazar.nextInt(ancGrilla);
subVerPosicion = alazar.nextInt(altGrilla);
Estas dos lineas las encontraran dentro de la funcion nuevo, las agregamos con este post, ahora para solucionar nuestro unico error vamos a modificar la funcion disparar de la siguiente forma:
void disparar(int x, int y) {
disparos++;
horizTocado = x / tamBloque;
vertTocado = y / tamBloque;
impacto = horizTocado == subHorPosicion
&& vertTocado == subVerPosicion;
int horBrecha = horizTocado - subHorPosicion;
int verBrecha = vertTocado - subVerPosicion;
distDesdeSub = (int) Math.sqrt((horBrecha * horBrecha)
+ (verBrecha * verBrecha));
if (impacto)
boom();
else
dibujar();
Log.d("Depurando","En el disparar()");
dibujar();
}
La primera modificacion sera darle la capacidad de recibir argumentos en esta funcion, a la cual llamaremos x e y de tipo int para recibir las coordenadas de los ejes X e Y respectivamente, con esto corregimos el error anterior, nuestra primera linea sera para incrementar el valor de disparos por medio del operador incrementador, nuestras siguientes lineas se encargaran de asignar valores a horizTocado y vertTocado, haciendo la division del valor informado en x e y dividido por tamBloque respectivamente, despues tendremos este bloque:
impacto = horizTocado == subHorPosicion
&& vertTocado == subVerPosicion;
En este caso almacenaremos en impacto el resultado de tipo booleano en la comparacion entre horizTocado y subHorPosicion y vertTocado y subVerPosicion, como usa un operador logico AND solo devolvera un valor verdadero si las dos condiciones son verdaderas, esto implicara que se impacto el submarino si el valor obtenido es verdadero (true), despues tendremos este bloque:
int horBrecha = horizTocado - subHorPosicion;
int verBrecha = vertTocado - subVerPosicion;
En este caso crearemos dos variables para calcular la brecha entre nuestro impacto y el submarino, para para ello calcularemos la diferencia entre los ejes donde tocamos la pantalla con los ejes del submarino, para luego asignar un valor a distDesdeSub y para ello usaremos el teorema de Pitagoras, el unico detalle es que usamos de nuevo (int) para que cambie el valor de la raiz cuadrada en tipo int y se lo asigne a la variable, esta accion se denomina habitualmente como castear, por ultimo tendremos un condicional donde verifica si impacto es verdadero, en caso de ser cierto llama a la funcion boom de lo contrario vuelve a llamar a dibujar, si lo probamos volvera a fallar porque boom todavia no existe, para solucionarlo vamos a agregar dicho metodo:
void boom()
{
juegoVista.setImageBitmap(bitmapBlanco);
canvas.drawColor(Color.argb(255,255,0,0));
pincel.setColor(Color.argb(255,255,255,255));
pincel.setTextSize(tamBloque * 10);
canvas.drawText("BOOM!", tamBloque * 4,
tamBloque * 14, pincel);
pincel.setTextSize(tamBloque * 2);
canvas.drawText("Dispara para jugar de nuevo!",
tamBloque * 8,
tamBloque * 18, pincel);
nuevo();
Log.d("Depurando","Hizo Boom! Verdaderamente");
}
En esta funcion nos encargaremos de mostrar el mensaje de impacto en el submarino, para ello primero setearemos el bitmapBlanco en nuestra vista, luego la pintamos completamente de rojo, pintaremos a nuestro pincel de blanco, para luego escribir nuestro mensaje de Boom!, cambiamos el tamaño del texto y luego otro mensaje para que vuelva a disparar para comenzar de nuevo, y por ultimo llamamos a nuevo para resetear todos los valores y comenzar nuevamente, antes de probar nuestra app veamos como quedo hasta ahora su codigo:
MainActivity
package org.example.cazadordesub;
import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Point;
import android.os.Bundle;
import android.util.Log;
import android.view.Display;
import android.view.MotionEvent;
import android.widget.ImageView;
import java.util.Random;
public class MainActivity extends Activity {
int numHorPixels;
int numVerPixels;
int tamBloque;
int ancGrilla;
int altGrilla;
int vertTocado;
int horizTocado;
int subHorPosicion;
int subVerPosicion;
boolean impacto;
int disparos;
boolean depuracion;
int distDesdeSub;
Display vista;
Point tamano;
ImageView juegoVista;
Bitmap bitmapBlanco;
Canvas canvas;
Paint pincel;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Log.d("Depurando","En el onCreate");
nuevo();
dibujar();
}
void dibujar()
{
bitmapBlanco = Bitmap.createBitmap(numHorPixels,
numVerPixels, Bitmap.Config.ARGB_8888);
canvas = new Canvas(bitmapBlanco);
juegoVista = new ImageView(this);
pincel = new Paint();
setContentView(juegoVista);
juegoVista.setImageBitmap(bitmapBlanco);
canvas.drawColor(Color.argb(255,255,255,255));
pincel.setColor(Color.argb(255,0,0,0));
for(int i=0; i < altGrilla; i++) {
canvas.drawLine(0, tamBloque * i,
numHorPixels - 1, tamBloque * i, pincel);
}
for(int i =0; i < ancGrilla; i++){
canvas.drawLine(tamBloque * i,0,
tamBloque * i, numVerPixels -1, pincel);
}
pincel.setTextSize(tamBloque * 1.5f);
pincel.setColor(Color.argb(255,0,0,255));
canvas.drawText("Disparos realizados: " +
disparos + " - Distancia del submarino: " +
distDesdeSub, tamBloque, tamBloque * 1.75f, pincel);
Log.d("Depurando","En el dibujar()");
imprimirDebug();
}
void nuevo()
{
vista = getWindowManager().getDefaultDisplay();
tamano = new Point();
vista.getSize(tamano);
numHorPixels = tamano.x;
numVerPixels = tamano.y;
ancGrilla = 40;
tamBloque = numHorPixels / ancGrilla;
altGrilla = numVerPixels / tamBloque;
disparos = 0;
distDesdeSub = 0;
impacto = false;
depuracion = true;
Random alazar = new Random();
subHorPosicion = alazar.nextInt(ancGrilla);
subVerPosicion = alazar.nextInt(altGrilla);
horizTocado = -100;
vertTocado = -100;
Log.d("Depurando","En el nuevo()");
}
void disparar(int x, int y) {
disparos++;
horizTocado = x / tamBloque;
vertTocado = y / tamBloque;
impacto = horizTocado == subHorPosicion
&& vertTocado == subVerPosicion;
int horBrecha = horizTocado - subHorPosicion;
int verBrecha = vertTocado - subVerPosicion;
distDesdeSub = (int) Math.sqrt((horBrecha * horBrecha)
+ (verBrecha * verBrecha));
if (impacto) {
boom();
}
else {
dibujar();
}
Log.d("Depurando","En el disparar()");
}
void boom()
{
juegoVista.setImageBitmap(bitmapBlanco);
canvas.drawColor(Color.argb(255,255,0,0));
pincel.setColor(Color.argb(255,255,255,255));
pincel.setTextSize(tamBloque * 10);
canvas.drawText("BOOM!", tamBloque * 4,
tamBloque * 14, pincel);
pincel.setTextSize(tamBloque * 2);
canvas.drawText("Dispara para jugar de nuevo!",
tamBloque * 8,
tamBloque * 18, pincel);
nuevo();
Log.d("Depurando","Hizo Boom! Verdaderamente");
}
void imprimirDebug()
{
pincel.setTextSize(tamBloque);
canvas.drawText("numHorPixels = " + numHorPixels,
50, tamBloque * 3, pincel);
canvas.drawText("numVerPixels = " + numVerPixels,
50, tamBloque * 4, pincel);
canvas.drawText("tamBloque = " + tamBloque,
50, tamBloque * 5, pincel);
canvas.drawText("ancGrilla = " + ancGrilla,
50, tamBloque * 6, pincel);
canvas.drawText("altGrilla = " + altGrilla,
50, tamBloque * 7, pincel);
canvas.drawText("subHorPosicion = " + subHorPosicion,
50, tamBloque * 8, pincel);
canvas.drawText("subVerPosicion = " + subVerPosicion,
50, tamBloque * 9, pincel);
canvas.drawText("horizTocado = " + horizTocado,
50, tamBloque * 10, pincel);
canvas.drawText("verTocado = " + vertTocado,
50, tamBloque * 11, pincel);
canvas.drawText("impacto = " + impacto,
50, tamBloque * 12, pincel);
canvas.drawText("depuracion = " + depuracion,
50, tamBloque * 13, pincel);
}
@Override
public boolean onTouchEvent(MotionEvent evento)
{
horizTocado = (int)evento.getX();
vertTocado = (int)evento.getY();
if ((evento.getAction() &
MotionEvent.ACTION_MASK) == MotionEvent.ACTION_UP){
disparar(horizTocado,vertTocado);
}
Log.d("Depurando","En el onTouchEvent");
Log.d("Depurando","horizTocado: " + horizTocado);
Log.d("Depurando","vertTocado: " + vertTocado);
return true;
}
}
A continuacion veremos un video donde pondremos a prueba todas las modificaciones y como quedo nuestro juego:
En el video podemos ver no solamente todos los datos de nuestro juego sino tambien que sucede cuando impactamos al submarino y como comenzamos nuevmente con el toque en la pantalla.
En resumen, hoy hemos dejado un juego completamente operativo, vimos como funciona el toque en pantalla, hicimos la parte encargada de recibir el disparo y compararla con la ubicacion del enemigo, en caso de falla nos indica cuan lejos estamos y si acertamos nos muestra el mensaje de explosion, 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.

Tambien podes donar
Es para mantenimiento del sitio, gracias!
$1.00