Anuncios

Bienvenidos sean a este post, hoy veremos como crear a nuestra clase encargada de manipular los toques en pantalla y convertirla en un listener.

Anuncios

Lo primero que debemos hacer es crear a nuestra nueva clase y para ello haremos click con el boton derecho sobre la carpeta donde estan las clases de Java y seleccionaremos New -> Java class y completaremos estos datos:

  • Nombre: UIcontroladora
  • Tipo: Class
Anuncios

Una vez generada nuestra clase vamos a convertirla en privada e implementar algunas clases (o interfaces en este caso) y para ello modificaremos el codigo generado automaticamente con el siguiente:

package org.example.invasores;

class UIcontroladora implements InputObservador {

    public UIcontroladora(GameEngineBroadcaster b){
        b.addObservador(this);
    }
}
Anuncios

En este caso solamente implementamos a nuestra interfaz InputObservador, aunque esto nos genera un error por ahora, y tambien creamos un constructor para agregar un observador, nuestro siguiente paso sera solucionar la implementacion de la interfaz y a su vez sera el interpretador del ArrayList que usamos en el GameEngine, para ello agregaremos el siguiente bloque:

    @Override
    public void handleInput(MotionEvent evento,
                            GameState estadoJuego,
                            ArrayList<Rect> botones){

        int i = evento.getActionIndex();
        int x = (int) evento.getX(i);
        int y = (int) evento.getY(i);

        int tipoEvento = evento.getAction() & MotionEvent.ACTION_MASK;

        if (tipoEvento == MotionEvent.ACTION_UP ||
                tipoEvento == MotionEvent.ACTION_POINTER_UP){

            if (botones.get(HUD.PAUSA).contains(x,y)){
                if(!estadoJuego.getPausado()){
                    estadoJuego.pausar();
                } else if (estadoJuego.getGameOver()){
                    estadoJuego.iniciaNuevoJuego();
                } else if (estadoJuego.getPausado()
                        && !estadoJuego.getGameOver()){
                    estadoJuego.retomar();
                }
            }
        }
    }
Anuncios

Como dijimos anteriormente las interfaces contienen los prototipos de los metodos que poseen, para este caso debemos usar Override y al momento de declararlo debemos usar los mismos argumentos, en este caso recibira tres:

  • Uno de tipo MotionEvent para manejar los toques en pantalla
  • Uno de GameState para saber cual es el estado del juego
  • Uno de tipo ArrayList para detectar cual boton fue apretado
Anuncios
Anuncios

En el bloque lo primero que haremos sera definir tres variables de tipo int, en la primera almacenaremos el indice almacenado en evento, en la siguiente almacenaremos el eje X dentro de evento y la ultima el eje Y de evento, despues definiremos una nueva variable donde por medio de getAction y ACTION_MASK de MotionEvent obtendremos como es el estado del toque en la pantalla, por ultimo tenemos este bloque de condicionales:

        if (tipoEvento == MotionEvent.ACTION_UP ||
                tipoEvento == MotionEvent.ACTION_POINTER_UP){

            if (botones.get(HUD.PAUSA).contains(x,y)){
                if(!estadoJuego.getPausado()){
                    estadoJuego.pausar();
                } else if (estadoJuego.getGameOver()){
                    estadoJuego.iniciaNuevoJuego();
                } else if (estadoJuego.getPausado()
                        && !estadoJuego.getGameOver()){
                    estadoJuego.retomar();
                }
            }
        }
Anuncios
Anuncios

El primer condicional chequea si uno de esos dos eventos se cumple, basicamente los dos eventos monitorean si se levanto el dedo de la pantalla, el cual es el evento mas importante para nosotros, el siguiente condicional verifica que la pulsacion fue dentro de las coordenadas del boton de pausa, en caso de ser cierto usaremos un bloque de condicionales if y else if para verificar los distintos estados del juego:

  • En el primer condicional verifica que el juego no este pausado y en caso de ser cierto llamar a pausar
  • En el segundo condicional verifica si estado es GameOver, en caso de ser verdadero llama al metodo para iniciar un nuevo juego
  • El ultimo condicional verifica es estado es pausado pero distinto de GameOver, en este caso considera que el juego esta pausado y en caso de ser cierto llamar a retomar para despausar el juego.
Anuncios

Con esto concluimos nuestra clase antes de pasar a la siguiente modificacion veamos el codigo de nuestra clase hasta ahora:

UIcontroladora.java

package org.example.invasores;

import android.graphics.Rect;
import android.view.MotionEvent;

import java.util.ArrayList;

class UIcontroladora implements InputObservador {

    public UIcontroladora(GameEngineBroadcaster b){
        b.addObservador(this);
    }

    @Override
    public void handleInput(MotionEvent evento,
                            GameState estadoJuego,
                            ArrayList<Rect> botones){

        int i = evento.getActionIndex();
        int x = (int) evento.getX(i);
        int y = (int) evento.getY(i);

        int tipoEvento = evento.getAction() & MotionEvent.ACTION_MASK;

        if (tipoEvento == MotionEvent.ACTION_UP ||
                tipoEvento == MotionEvent.ACTION_POINTER_UP){

            if (botones.get(HUD.PAUSA).contains(x,y)){
                if(!estadoJuego.getPausado()){
                    estadoJuego.pausar();
                } else if (estadoJuego.getGameOver()){
                    estadoJuego.iniciaNuevoJuego();
                } else if (estadoJuego.getPausado()
                        && !estadoJuego.getGameOver()){
                    estadoJuego.retomar();
                }
            }
        }
    }
}
Anuncios

Nuestra siguiente modificacion sera la implementacion de esta clase en el GameEngine para poder usarla, para ello iremos a esta clase y en donde tenemos las declaraciones al comienzo de la misma y agregaremos esta linea:

UIcontroladora mUIcontroladora;
Anuncios

Con esto creamos el objeto de la clase, nuestro siguiente paso sera definirlo en el constructor de esta clase y para ello agregaremos esta linea dentro del bloque pero despues de la llamada a super:

mUIcontroladora = new UIcontroladora(this);
Anuncios

Con esta modificacion podemos probar nuestro juego pero antes veamos como quedo nuestro codigo de la clase GameEngine:

GameEngine.java

package org.example.invasores;

import android.content.Context;
import android.graphics.Point;
import android.util.Log;
import android.view.MotionEvent;
import android.view.SurfaceView;

import java.util.ArrayList;

class GameEngine extends SurfaceView implements Runnable,
        Iniciador, GameEngineBroadcaster {
    private Thread mThread = null;
    private long mFPS;

    UIcontroladora mUIcontroladora;

    private ArrayList<InputObservador> inputObservadores =
            new ArrayList<>();

    private GameState mGameState;
    private SoundEngine mSoundEngine;

    HUD mHud;
    Renderer mRenderer;

    public GameEngine(Context contexto, Point tamano){
        super(contexto);
        mUIcontroladora = new UIcontroladora(this);
        mGameState = new GameState(this, contexto);
        mSoundEngine = new SoundEngine(contexto);
        mHud = new HUD(tamano);
        mRenderer = new Renderer(this);
    }

    public void addObservador(InputObservador o){
        inputObservadores.add(o);
    }

    @Override
    public void run(){
        while(mGameState.getThreadCorriendo()){
            long frameInicio = System.currentTimeMillis();
            if (!mGameState.getPausado()){

            }
            mRenderer.dibujar(mGameState,mHud);
            long frameActual = System.currentTimeMillis() - frameInicio;
            if (frameActual >= 1){
                final int MILISEGUNDOS = 1000;
                mFPS = MILISEGUNDOS / frameActual;
            }
        }
    }

    @Override
    public boolean onTouchEvent(MotionEvent evento){
        for(InputObservador o : inputObservadores){
            o.handleInput(evento,mGameState,mHud.getControles());
        }
        return true;
    }

    public void stopThread(){
        mGameState.detenerTodo();

        try{
            mThread.join();
        } catch (InterruptedException e){
            Log.e("Exception","stopThread" +
                    e.getMessage());
        }
    }

    public void startThread(){
        mGameState.startThread();
        mThread = new Thread(this);
        mThread.start();
    }

    public void desapareceReaparece(){

    }
}
Anuncios

Con esta modificacion realizada podemos pasar a probar como esta quedando nuestro juego hasta ahora, compilemos y veamos como es su salida mediante el siguiente video

Anuncios

En este ocasion podemos ver como “comienza” el juego, como se pausa (nos lo muestra en pantalla) y vuelve a retomar el juego, es un decir porque todavia no tenemos el juego en si, pero espero que vayan captando la idea.

Anuncios

En resumen, hoy hemos creado la clase que se encargara de supervisar nuestros botones, en este caso hemos hecho una inicial que se encarga de monitorear el estado del juego para iniciar un nuevo juego y en base a ellos inicia un nuevo juego o estado, pausa el mismo o lo retoma, tambien lo hemos implementado en nuestro juego y lo hemos probado para ver su nueva funcionalidad, 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.

Anuncios

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