Anuncios

Bienvenidos sean a este post, hasta el post anterior hemos creado todas las clases necesarias, hoy vamos a completar los componentes para el jugador.

Anuncios

Para comenzar vamos a volver a nuestra clase ComponentesGraficosStd en la cual tenemos dos metodos solamente, inicializar y dibujar, para iniciar con el tema de hoy vamos a agregar el codigo para inicializar:

    @Override
    public void inicializar(Context contexto,
                            ObjetoEspec espec,
                            PointF tamanoObjeto){
        int resID = contexto.getResources()
                .getIdentifier(espec.getBitmapNombre(),
                        "drawable",
                        contexto.getPackageName());
        mBitmap = BitmapFactory.decodeResource(
                contexto.getResources(), resID);
        mBitmap = Bitmap.createScaledBitmap(
                mBitmap,
                (int)tamanoObjeto.x,
                (int)tamanoObjeto.y,
                false);
        Matrix matrix = new Matrix();
        matrix.setScale(-1,1);
        mBitmapInverso = Bitmap.createBitmap(
                mBitmap,
                0,0,
                mBitmap.getWidth(),
                mBitmap.getHeight(),
                matrix,
                true);
    }
Anuncios
Anuncios

Lo primero que haremos sera crear una variable la cual nos servira almacenar el id del recurso que obtendremos en base al nombre del archivo, para ello por medio de getResources y el contexto de nuestra clase, usamos el getIdentifier donde le pasamos la especificacion en espec y por medio de getBitmapNombre, lo siguiente va a ser el tipo de definicion (para este caso usamos a drawable), y por ultimo usamos a getPackageName para obtener el nombre del paquete, con todo esto ya obtenemos el identificador del archivo, lo siguiente sera a asignar el recurso o la imagen al objeto mBitmap, para ello usamos decodeResource del BitmapFactory, lo siguiente sera a getResources para ubicarlo en nuestra clase R que es la ubicacion de los recursos, el siguiente es el id que obtuvimos antes, con todo esto logramos tener nuestra imagen en mBitmap, lo siguiente sera escalar a la imagen y para ello usamos a createScaledBitmap, le pasamos el objeto almacenado en mBitmap, seguido de los ejes X e Y que tenemos en tamanoObjeto, por ultimo un filtro.

Anuncios

Para nuestro siguiente paso crearemos la matriz, primero creamos el objeto, luego seteamos la escala de esta matrix y por ultimo tal como hicimos con Snake usamos a mBitmapInverso para invertir el mBitmap por medio de matrix, con esto ultimo ya tenemos la opcion de poder invertir cualquier imagen que nos llegue, es decir que ya podemos trabajar tanto con el jugador como los enemigos, pasemos a nuestro siguiente metodo:

    @Override
    public void dibujar(Canvas canvas,
                        Paint pincel,
                        Transformar t){
        if (t.getMirandoDerecha()){
            canvas.drawBitmap(mBitmap,
                    t.getPosicion().x,
                    t.getPosicion().y,
                    pincel);
        } else {
            canvas.drawBitmap(mBitmapInverso,
                    t.getPosicion().x,
                    t.getPosicion().y,
                    pincel);
        }
    }
Anuncios
Anuncios

Como pueden ver el metodo no es muy complejo, sino que simplemente verifica si mMirandoDerecha de nuestra clase Transformar es verdadero, en caso de ser cierto utiliza el canvas para dibujarlo y le pasa a mBitmap como imagen despues usa a getPosicion para obtener el eje X e Y, en caso contrario vuelve a repetir la operacion pero en lugar de usar a mBitmap va a ser mBitmapInverso, lo bueno de trabajar de esta forma es que todo se hara cuando ejecutamos inicializar y dibujar simplemente mostrara las imagenes que establecimos, con esto terminamos a nuestra clase pasemos a la siguiente.

Anuncios

En este caso vamos a ver el componente de movimiento, esta sera la encargada de concederle movimiento a nuestra nave pero todavia no va a ser funcional porque por el momento no hablamos sobre el tema de la entrada del jugador, pasemos a nuestra clase ComponenteJugadorMovimiento, en al cual tenemos un solo metodo al cual modificaremos de la siguiente manera:

    @Override
    public boolean mover(long fps,
                         Transformar t,
                         Transformar jugadorTransformar){
        float pantallaAltura = t.getTamanoPantalla().y;
        PointF ubicacion = t.getPosicion();
        float velocidad = t.getVelocidad();
        float altura = t.getObjetoAltura();

        if (t.apuntandoAbajo()){
            ubicacion.y += velocidad / fps;
        }
        else if (t.apuntandoArriba()){
            ubicacion.y -= velocidad / fps;
        }

        if (ubicacion.y > (pantallaAltura - altura)){
            ubicacion.y = pantallaAltura - altura;
        }
        else if (ubicacion.y < 0){
            ubicacion.y = 0;
        }
        
        t.actualizaColision();
        return true;
    }
Anuncios

Lo primero que tendremos en nuestra clase seran cuatro variables:

  • pantallaAltura, para almacenar la altura de la pantalla
  • ubicacion, la ubicacion del jugador
  • velocidad, la velocidad del jugador
  • altura, la altura del jugador
Anuncios
Anuncios

Despues tendremos un condicional donde verifica si esta apuntando para abajo, en caso de ser cierto procede a incrementar el valor del eje Y en ubicacion con la division de velocidad y fps, en caso contrario verifica si esta apuntando hacia arriba y en caso de ser verdadero disminuira el valor del eje y con la formula anterior, el siguiente condicional esta para que nuestra nave no se vaya de la pantalla, para ello primero verifica si el eje Y de ubicacion es mayor a la diferencia entre la altura de la pantalla y la altura de nuestra nave, en caso de ser verdadero establece el resultado de esta operacion como limite, de lo contrario verifica si el eje Y es menor a cero y en caso de ser verdadero siempre lo deja en cero, por ultimo llamamos a actualizarColision para verificar como esta nuestra nave con respecto a los demas, por ahora no tenemos nada que verificar pero mas adelante si nos sera util, para nuestro siguiente paso vamos a confeccionar el ComponenteGeneraJugador.

Anuncios

Nos dirigimos a esta clase, en la cual tenemos un solo metodo que lo modificaremos de la siguiente manera:

    @Override
    public void generar(Transformar jugadorTransformar,
                        Transformar t){
        t.setPosicion(t.getTamanoPantalla().x/2,
                t.getTamanoPantalla().y/2);
    }
Anuncios

En ambos casos dividimos al valor de X e Y devuelto por getTamanoPantalla y lo pasamos a setPosicion, por ahora dejaremos en paz al jugador y vamos a pasar a hablar del laser, la primera modificacion la haremos en ComponenteLaserMovimiento.

Anuncios

Vamos a ir a nuestro metodo mover y lo modificaremos de la siguiente manera:

package org.example.invasores;

import android.graphics.PointF;

class ComponenteLaserMovimiento implements ComponenteMovimiento {
    @Override
    public boolean mover(long fps,
                         Transformar t,
                         Transformar jugadorTransformar){
        float rango = t.getTamanoPantalla().x * 2;
        PointF ubicacion = t.getPosicion();
        float velocidad = t.getVelocidad();

        if (t.apuntandoDerecha()){
            ubicacion.x += velocidad / fps;
        }
        else if (t.apuntandoIzquierda()){
            ubicacion.x -= velocidad / fps;
        }

        if (ubicacion.x < -rango || ubicacion.x > rango)
            return false;
        
        t.actualizaColision();
        return true;
    }
}
Anuncios
Anuncios

Si lo ven bien, es muy parecido a cuando hablamos de los movimientos del jugador, la diferencia esta en lugar de usar el tamaño de pantalla usa a rango para tener el doble del ancho de pantalla, luego explicaremos porque el doble cuando hablemos del fondo, ubicacion y velocidad son similares, luego tendremos un condicional donde verifica si esta apuntando a la derecha, en caso de ser cierto incrementa el eje x de la misma manera que antes, en caso de no ser cierto en lugar de sumarlo lo resta, en este caso usamos el eje X porque el laser se desplazara por la pantalla de forma horizontal ya sea para un lado o para el otro, sea el jugador o un enemigo, el siguiente condicional verifica si el eje X de ubicacion es menor al valor negativo de rango o mayor a rango, si se cumplen cualquiera de las dos condiciones devuelve un false para desaparecer el laser, por ultimo volvemos a llamar a actualizaColision y seguimos devolviendo true, pasemos a nuestra siguiente clase ComponenteGeneraLaser.

Anuncios

Como todos los casos anteriores vamos a completar al metodo generar de la siguiente manera:

package org.example.invasores;

import android.graphics.PointF;

class ComponenteGeneraLaser implements ComponenteGenerar {
    @Override
    public void generar(Transformar jugadorTransformar,
                        Transformar t){
        PointF posicionInicial = jugadorTransformar
                .getPosicionDisparo(t.getTamano().x);
        t.setPosicion((int)posicionInicial.x,
                (int)posicionInicial.y);
        
        if(jugadorTransformar.getMirandoDerecha())
            t.apuntarDerecha();
        else
            t.apuntarIzquierda();
    }
}
Anuncios

El primer objeto de tipo PointF sera para guardar la posicion inicial, lo siguiente sera establecer la posicion del disparo por medio de setPosicion a traves del valor establecido anteriormente, luego tendremos un condicional donde verifica si esta mirando a la derecha y procede a llamar a apuntarDerecha de lo contrario llama a apuntarIzquierda, con esto ya tenemos a nuestro laser terminado y podemos pasar al ultimo componente que es el encargado de controlar las entradas.

Anuncios

Para ello debemos ir a la clase ComponenteEntradaJugador donde modificaremos a los tres metodos de la siguiente manera:

    ComponenteEntradaJugador(GameEngine ger){
        ger.addObservador(this);
        mGLJ = ger;
    }

    @Override
    public void setTransformar(Transformar transformar){
        mTransformar = transformar;
    }

    @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);

        switch(evento.getAction() & MotionEvent.ACTION_MASK){
            case MotionEvent.ACTION_UP:
                if (botones.get(HUD.ARRIBA).contains(x,y)
                        || botones.get(HUD.ABAJO).contains(x,y)){
                    mTransformar.pararVertical();
                }
                break;
            case MotionEvent.ACTION_DOWN:
                if (botones.get(HUD.ARRIBA).contains(x,y))
                    mTransformar.apuntarArriba();
                else if (botones.get(HUD.ABAJO).contains(x,y))
                    mTransformar.apuntandoAbajo();
                else if (botones.get(HUD.VUELTA).contains(x,y))
                    mTransformar.voltear();
                else if (botones.get(HUD.DISPARO).contains(x,y))
                    mGLJ.generaLaserJugador(mTransformar);
                break;
            case MotionEvent.ACTION_POINTER_UP:
                if (botones.get(HUD.ARRIBA).contains(x,y)
                        || botones.get(HUD.ABAJO).contains(x,y)){
                    mTransformar.pararVertical();
                }
                break;
            case MotionEvent.ACTION_POINTER_DOWN:
                if (botones.get(HUD.ARRIBA).contains(x,y))
                    mTransformar.apuntarArriba();
                else if (botones.get(HUD.ABAJO).contains(x,y))
                    mTransformar.apuntandoAbajo();
                else if (botones.get(HUD.VUELTA).contains(x,y))
                    mTransformar.voltear();
                else if (botones.get(HUD.DISPARO).contains(x,y))
                    mGLJ.generaLaserJugador(mTransformar);
                break;
        }
    }
Anuncios

El primero sera el constructor y se encargara de agregar un nuevo observador y esto permitira recibir una notificacion cada vez que se toque la pantalla, inicia a mGLJ por medio del GameEngine recibido, en el segundo metodo referenciamos a mTransformar con el Transformar que se encuentra en GameObjeto, esto es gracias a handleInput que se encarga de manejar a Transformar y el ComponenteMovimientoJugador responde a estas manipulaciones ya que el metodo onTouchevent en el GameEngine se encarga de llamar a handleInput porque ComponenteMovimientoJugador esta registrado como un observador.

Anuncios

Nuestro siguiente metodo es handleInput, en este caso tenemos primero tres variables:

  • i, se encarga de almacenar el indice del evento
  • x, el valor del eje X del evento almacenado en i
  • y, el eje Y del evento almacenado en i
Anuncios

Despues tenemos un switch que se encarga de monitorear las acciones de tocar que hubo en nuestra pantalla, el primer case sera para ver cuando sacamos el dedo de la pantalla, tiene un condicional donde verifica si se solto al boton para abajo o para arriba y en cualquiera de los dos casos llama a pararVertical, el siguiente case verifica si se esta presionado la pantalla, en este caso verifica a los cuatro botones disponibles:

  • Si se presiona HUD.ARRIBA llama a apuntarArriba
  • Si se presiona HUD.ABAJO se llama a apuntarAbajo
  • Si se presiona HUD.VUELTA se llama a voltear
  • Si se presiona HUD.DISPARO, en este caso se llama generaLaserJugador
Anuncios

En todos los casos para verificar que se presiona se verifica que cualquiera de los botones contenga los ejes X e Y al momento de verificarlo, los siguientes dos case son iguales a los anteriores pero en este caso verifican a los punteros, esto lo hacemos para que evalue todas las posibilidades, con todo ya tenemos cubierto todos los componentes para nuestro jugador.

Anuncios

En resumen, hoy hemos visto como completar todos los metodos para cada uno de los componentes que involucran a nuestro jugador, tambien hemos completado dos clases que nos involucran a otros elementos como son los graficos, o el laser de los enemigos, tambien hemos visto como implementar una forma simple para invertir las imagenes, tambien un metodo unico para nuestro jugador como es el movimiento pero sin cerrar la posibilidad de poder implementarlo en otro objeto, 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