Anuncios

Bienvenidos sean a este post, hoy llego el gran dia porque hasta ahora creamos todo lo necesario desde los componentes hasta el nivel donde contiene todo pero hoy veremos como implementarlo en nuestro juego.

Anuncios

Para comenzar debemos ir a nuestra clase GameEngine en donde estan todas las declaraciones de las variables/objetos agregaremos la siguiente linea:

Nivel mNivel;
Anuncios

Con esto declaramos a nuestro nuevo objeto, el siguiente paso sera definirlo en el constructor de la clase, para ello agregaremos el siguiente bloque:

        mNivel = new Nivel(contexto,
                new PointF(tamano.x,tamano.y),
                this);
Anuncios

En este caso simplemente creamos el nivel en memoria, el contexto, el tamaño de la pantalla y el GameEngine que en este caso lo hacemos a traves del this, nuestra siguiente modificacion sera en el metodo desapareceReaparece, el cual sera llamado por GameState cuando necesite aparecer o desaparecer los objetos en el nivel, veamos como debemos modificarlo:

    public void desapareceReaparece(){
        ArrayList<GameObjeto> objetos = mNivel.getObjetos();
        for(GameObjeto o : objetos){
            o.setInactivo();
        }

        objetos.get(Nivel.INDICE_JUGADOR)
                .generar(objetos.get(Nivel.INDICE_JUGADOR)
                        .getTransformar());
        objetos.get(Nivel.INDICE_FONDO)
                .generar(objetos.get(Nivel.INDICE_FONDO)
                        .getTransformar());
    }
Anuncios
Anuncios

Este metodo sera el encargado de aparecer y desaparecer todos los objetos en nuestro nivel, para ello crearemos un nuevo objeto llamado objetos donde estaran todos los GameObjeto de nivel, despues a traves de un for mejorado setearemos a todos como inactivos, luego le diremos que por medio de get obtenga al objeto que sera el jugador, lo genera y por ultimo obtiene el objeto Transformar del jugador, lo mismo hacemos para el fondo, en este caso solo obtendremos dos objetos pero proximamente agregaremos los restantes, pasemos a modificar el siguiente metodo:

    @Override
    public boolean generaLaserJugador(Transformar transformar){
        ArrayList<GameObjeto> objetos = mNivel.getObjetos();

        if (objetos.get(Nivel.mProximoLaserJugador)
                .generar(transformar)){
            Nivel.mProximoLaserJugador++;
            mSoundEngine.repDisparar();
            if (Nivel.mProximoLaserJugador >= Nivel.ULTIMO_LASER_JUGADOR){
                Nivel.mProximoLaserJugador = Nivel.PRIMER_LASER_JUGADOR;
            }
        }
        return true;
    }
Anuncios
Anuncios

Este sera el metodo encargado de generar los lasers del jugador, al igual que el caso anterior crearemos un objeto para almacenar los objetos del nivel, luego usaremos un condicional donde genera al “laser”, en caso de ser verdadero incrementa el valor de mProximoLaserJugador, luego reproduce el sonido del disparo, despues verifica si mProximoLaserJugador es mayor o igual a ULTIMO_LASER_JUGADOR y en caso de ser verdadero establece el valor del proximo laser con el primer laser del jugador, por ultimo devuelve un true, nuestro siguiente paso sera modificar el metodo run de la siguiente forma:

    @Override
    public void run(){
        while(mGameState.getThreadCorriendo()){
            long frameInicio = System.currentTimeMillis();
            ArrayList<GameObjeto> objetos = mNivel.getObjetos();

            if (!mGameState.getPausado()){
                if (mFisicasEngine.actualizar(mFPS,objetos,mGameState,
                        mSoundEngine,mSistemaParticula))
                    desapareceReaparece();
            }
            mRenderer.dibujar(objetos,mGameState,mHud,mSistemaParticula);
            long frameActual = System.currentTimeMillis() - frameInicio;
            if (frameActual >= 1){
                final int MILISEGUNDOS = 1000;
                mFPS = MILISEGUNDOS / frameActual;
            }
        }
    }
Anuncios

En este metodo hicimos sutiles diferencias, la primera fue agregar esta linea:

ArrayList<GameObjeto> objetos = mNivel.getObjetos();
Anuncios

Hace exactamente lo mismo que estuvimos viendo hasta ahora, la siguiente modificacion fue en este bloque:

if (mFisicasEngine.actualizar(mFPS,objetos,mGameState,
        mSoundEngine,mSistemaParticula))
    desapareceReaparece();
Anuncios

Donde modificamos los argumentos de dos a cinco argumentos, esto ocasionara que nos genere un error momentaneamente, y este se encargara de desaparecer o reaparecer los objetos que reciban un impacto, la siguiente modificacion es este bloque:

mRenderer.dibujar(objetos,mGameState,mHud,mGameState);
Anuncios

Este en lugar de recibir los tres argumentos que esperaba recibe cuatro, en ambos casos entre otras cosas le enviamos a objetos, con esto terminamos las modificaciones en la clase GameEngine solo nos resta solucionar los dos problemas que nos aparecieron con estas ultimas modificaciones, vamos a arreglar la primera yendo a la clase FisicasEngine y modificaremos esta linea:

 boolean actualizar(long fps, SistemaParticula sp){
Anuncios

De la siguiente forma:

    boolean actualizar(long fps, 
                       ArrayList<GameObjeto> objetos, 
                       GameState gs, 
                       SoundEngine se, 
                       SistemaParticula sp){
Anuncios

Con esto podremos recibir todos los datos que decidimos enviarle desde el GameEngine, el siguiente paso es agregar las siguientes lineas dentro del bloque del metodo:

        for(GameObjeto objeto : objetos){
            if (objeto.chekaActivo()){
                objeto.actualizar(fps,
                        objetos.get(Nivel.INDICE_JUGADOR)
                                .getTransformar());
            }
        }
Anuncios

En este caso pasamos por todos los objetos informados, luego usamos a chekaActivo para saber si esta activo o no, en caso de ser verdadero procede a actualizar el objeto con el valor de Transformar, el codigo queda de la siguiente manera:

FisicasEngine.java

package org.example.invasores;

import java.util.ArrayList;

class FisicasEngine {
    boolean actualizar(long fps,
                       ArrayList<GameObjeto> objetos,
                       GameState gs,
                       SoundEngine se,
                       SistemaParticula sp){
        for(GameObjeto objeto : objetos){
            if (objeto.chekaActivo()){
                objeto.actualizar(fps,
                        objetos.get(Nivel.INDICE_JUGADOR)
                                .getTransformar());
            }
        }

        if (sp.mEstaCorriendo)
            sp.actualizar(fps);

        return false;
    }
}
Anuncios

Lo siguiente sera la modificacion de la clase Renderer donde primero modificaremos esta linea:

void dibujar(GameState gs, HUD hud, SistemaParticula sp){
Anuncios

De la siguiente manera:

    void dibujar(ArrayList<GameObjeto> objetos, GameState gs, 
                 HUD hud, SistemaParticula sp){
Anuncios

Como podemos ver ahora tenemos los cuatro atributos que nos envia GameEngine, la siguiente modificacion sera en el condicional que verifica si se esta dibujando, el cual actualmente esta vacio y lo completaremos de la siguiente manera:

            if (gs.getDibujando()){
                for(GameObjeto objeto : objetos){
                    if (objeto.chekaActivo())
                        objeto.dibujar(mCanvas,pincel);
                }
            }
Anuncios

En este caso cada vez que este dibujando ejecutara un bucle que pasara por todos los objetos donde chequea objeto por objeto si esta activo y en caso de ser verdadero procede a dibujarlo, nuestra siguiente modificacion sera en el condicional donde verifica si se termino el juego, el cual al igual que en el caso anterior esta en blanco pero lo modificaremos de la siguiente manera:

            if (gs.getGameOver()){
                objetos.get(Nivel.INDICE_FONDO).dibujar(mCanvas,pincel);
            }
Anuncios

En este caso hacemos que dibuje el fondo de pantalla, por ahora, con esto ya tenemos todas las modificaciones realizadas pasemos a ver el codigo de nuestra clase hasta ahora:

Renderer.java

package org.example.invasores;

import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.view.SurfaceHolder;
import android.view.SurfaceView;

import java.util.ArrayList;

class Renderer {
    private Canvas mCanvas;
    private SurfaceHolder mSurfaceHolder;
    private Paint pincel;

    Renderer(SurfaceView sv){
        mSurfaceHolder = sv.getHolder();
        pincel = new Paint();
    }

    void dibujar(ArrayList<GameObjeto> objetos, GameState gs,
                 HUD hud, SistemaParticula sp){
        if (mSurfaceHolder.getSurface().isValid()){
            mCanvas = mSurfaceHolder.lockCanvas();
            mCanvas.drawColor(Color.argb(255,0,0,0));

            if (gs.getDibujando()){
                for(GameObjeto objeto : objetos){
                    if (objeto.chekaActivo())
                        objeto.dibujar(mCanvas,pincel);
                }
            }

            if (gs.getGameOver()){
                objetos.get(Nivel.INDICE_FONDO).dibujar(mCanvas,pincel);
            }

            if (sp.mEstaCorriendo)
                sp.dibujar(mCanvas,pincel);

            hud.dibujar(mCanvas,pincel,gs);
            mSurfaceHolder.unlockCanvasAndPost(mCanvas);
        }
    }
}
Anuncios

Con todo esto ya tenemos nuestro juego bastante avanzado y podemos probarlo, compilemos como funciona hasta ahora en el siguiente video

Anuncios

Como pueden ver funciona de diez, solo me falto probar como sube y baja pero les aseguro que funciona tambien, con esto ya tenemos cubierto como mover el fondo, el disparo, el sonido del disparo y el volteo, nuestro siguiente paso seran los enemigos pero este tema sera un tema arduo y complejo que lo veremos en diferentes posts.

Anuncios

En resumen, hoy hemos implementado todo lo visto en los posts anteriores, hemos visto como implementarlo en el GameEngine, las modificaciones que se deben realizar, por ultimo lo hemos probado y comprobado como esta funcionando con nuestro GameObjetos, 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