Robots 2d

CLASE PRINCIPAL

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package robots2D;

import java.io.File;
import org.lwjgl.LWJGLUtil;
import org.newdawn.slick.*;
import org.newdawn.slick.Input.*;
import org.newdawn.slick.font.effects.ColorEffect;
import org.newdawn.slick.tiled.*;

/**
 * JUEGO DE LOS ROBOTS - aplicación base para el desarrollo del examen de la segunda evaluación
 *
 *
 */
public class Robots2D extends BasicGame {

    // Tilemap
    private TiledMap mapa;
   
    // Estado del jugador
    private float jugadorX, jugadorY;
    private SpriteSheet cuadros;
    private SpriteSheet cuadrosRobot;
   
   
    // Posición del corazón
    private float corazonX, corazonY;
    private Image corazon;
   
    // NUEVO: Para almacenar la explosión
    private SpriteSheet explosion;
   
   
    private Animation jugador;
    private Animation jugadorArriba;
    private Animation jugadorDerecha;
    private Animation jugadorAbajo;
    private Animation jugadorIzquierda;
    private boolean jugadorVivo;
   
    // Estado de los robots
    private Animation[] robot;
    private Animation robotArriba;
    private Animation robotDerecha;
    private Animation robotAbajo;
    private Animation robotIzquierda;
    private float[] robotX, robotY;
    private boolean[] robotVivo;
    private boolean[] robotVisible;
    private float[] robotVelocidad;
    private int numeroRobotsVivos;
    private static final int TOTAL_ROBOTS = 30;
   
    // Escritura de cadenas
    private UnicodeFont fuente;
   
    // Contador de tiempo
    private long tiempo;
   
    // NUEVO: Música y sonidos
    private Music musica;
    private Sound sonido;

    public Robots2D(String name) {
        super(name);
    }

    public static void main(String[] args) {
        System.setProperty("org.lwjgl.librarypath", new File(new File(System.getProperty("user.dir"), "native"), LWJGLUtil.getPlatformName()).getAbsolutePath());
        System.setProperty("net.java.games.input.librarypath", System.getProperty("org.lwjgl.librarypath"));
        try {
            AppGameContainer container = new AppGameContainer(new Robots2D("PMDM06 - Tarea"));
            container.setDisplayMode(640, 480, false);
            container.setTargetFrameRate(60);
            container.setVSync(true);
            container.setShowFPS(false);
            container.setUpdateOnlyWhenVisible(false);
            container.start();
        } catch (SlickException e) {
        }
    }

    @Override
    public void init(GameContainer gc) throws SlickException {
       


        // cargar mapa
        mapa = new TiledMap("data/mapa.tmx", "data");
       
       
        corazon = new Image("data/corazon.png");

        // cargar spritesheets
        cuadros = new SpriteSheet("data/heroe.png", 24, 32);
        cuadrosRobot = new SpriteSheet("data/robot.png", 24, 32);
        explosion = new SpriteSheet("data/explosion.png", 32, 32); // NUEVO

        // cargar animaciones del jugador
        jugadorArriba = new Animation(cuadros, 0, 0, 2, 0, true, 150, false);
        jugadorDerecha = new Animation(cuadros, 0, 1, 2, 1, true, 150, false);
        jugadorAbajo = new Animation(cuadros, 0, 2, 2, 2, true, 150, false);
        jugadorIzquierda = new Animation(cuadros, 0, 3, 2, 3, true, 150, false);
        jugador = jugadorAbajo;

        // cargar animaciones del robot
        robotArriba = new Animation(cuadrosRobot, 0, 0, 2, 0, true, 150, true);
        robotDerecha = new Animation(cuadrosRobot, 0, 1, 2, 1, true, 150, true);
        robotAbajo = new Animation(cuadrosRobot, 0, 2, 2, 2, true, 150, true);
        robotIzquierda = new Animation(cuadrosRobot, 0, 3, 2, 3, true, 150, true);

        // estado inicial del jugador
        jugadorX = 320;
        jugadorY = 240;
        jugadorVivo = true;

        // estado inicial de los robots      
        robot = new Animation[TOTAL_ROBOTS];
        robotX = new float[TOTAL_ROBOTS];
        robotY = new float[TOTAL_ROBOTS];
        robotVivo = new boolean[TOTAL_ROBOTS];
        robotVelocidad = new float[TOTAL_ROBOTS];

        // NUEVO: Un robot puede estar muerto pero visible mientras explota
        robotVisible = new boolean[TOTAL_ROBOTS];

        numeroRobotsVivos = TOTAL_ROBOTS;

        // los colocamos repartidos al azar
        for (int i=0;i<TOTAL_ROBOTS;i++) {
           
            // Cogemos una coordenada X alejada del centro
            float X = (float)((Math.random()*(gc.getWidth()/2-100)));
            // ¿En la izquierda o en la derecha?
            if (Math.random()<0.5f) {
                robotX[i] = X;
                robot[i] = robotDerecha;     // mirar a la derecha
            }
            else {
                robotX[i] = gc.getWidth()-X;
                robot[i] = robotIzquierda;    // mirar a la izquierda
            }
                  
            // Cogemos una coordenada Y alejada del centro teniendo en cuenta
            // que los primeros 64 píxeles no se pueden usar porque está
            // el marcador
            float Y = 64 + (float)((Math.random()*(gc.getHeight()/2-132)));
            // ¿En la parte de arriba o de abajo?
            if (Math.random()<0.5f) {
                robotY[i] = Y;
            }
            else {
                robotY[i] = gc.getHeight()-Y;
            }
          
        }
       
        corazonX = (float)((Math.random()*(gc.getWidth()/2)));
        corazonY = 64 + (float)((Math.random()*(gc.getHeight()/2)));

        // indicamos que, de momento, los robots están vivos
        for (int i = 0; i < TOTAL_ROBOTS; i++) {
            robotVivo[i] = true;
            robotVisible[i] = true;
            // NUEVO: Que algunos empiecen más o menos rápidos
            robotVelocidad[i] = 0.25f + 0.5f * (float) Math.random();
        }

        // cargar tipo de letra de la carpeta data y todos los símboles
        // que podamos necesitar       
        fuente = new UnicodeFont("data/tuffy.ttf", 28, false, false);
        // añade las letras ASCII estándar
        fuente.addAsciiGlyphs();
        // y ahora añadimos los caracteres españoles
        fuente.addGlyphs("áéíóúÁÉÍÓÚñÑ¡¿");
        // en Slick es obligatorio añadir un efecto para poder dibujar
        // texto. Añadimos un efecto vacío.
        fuente.getEffects().add(new ColorEffect(java.awt.Color.WHITE));
        // cargamos los símbolos del tipo de letra
        fuente.loadGlyphs();

        // a partir de ahora, llamado a fuente.drawString(x, y, texto) ¡podremos
        // escribir en el contenedor!

        // NUEVO: Añadimos música de fondo y cargamos los efectos de sonido
        musica = new Music("data/tuturne land!.mod");
        sonido = new Sound("data/8bit_bomb_explosion.wav");
        musica.loop();

        // comenzar cuenta de tiempo. Apuntamos el número que contiene el
        // reloj del sistema en milisegundos. De esta forma, restando esta
        // cantidad a la cuenta actual nos dice el número de milisengudos
        // que han transcurrido.
        tiempo = System.currentTimeMillis();
       
       
               
       
       
    }

    @Override
    public void update(GameContainer gc, int delta) throws SlickException {
        Input entrada = gc.getInput();

        // si se pulsa Esc, salir
        if (entrada.isKeyDown(Input.KEY_ESCAPE)) {    // Tecla ESC
            gc.exit();
        }
       
        // si no quedan robots o ha muerto el jugador, no actualizar nada
        if ((jugadorVivo == false) || (numeroRobotsVivos == 0)) {
            return;
        }

        // movimiento del jugador
        if (entrada.isKeyDown(Input.KEY_DOWN)) {    // Tecla abajo
            jugadorY += delta * 0.1f;
            // evitar que nos salgamos por la parte inferior del contenedor
            if (jugadorY > (gc.getHeight() - jugador.getHeight())) {
                jugadorY = (gc.getHeight() - jugador.getHeight());
            }
            jugador = jugadorAbajo;
            jugador.update(delta);
        }
        if (entrada.isKeyDown(Input.KEY_UP)) {    // Tecla arriba
            jugadorY -= delta * 0.1f;
            // evitar que nos salgamos por la parte superior del contenedor
            if (jugadorY < 32) {
                jugadorY = 32;
            }
            jugador = jugadorArriba;
            jugador.update(delta);
        }
        if (entrada.isKeyDown(Input.KEY_RIGHT)) {    // Tecla derecha
            jugadorX += delta * 0.1f;
            // evitar que nos salgamos por la derecha del contenedor
            if (jugadorX > (gc.getWidth() - jugador.getWidth())) {
                jugadorX = (gc.getWidth() - jugador.getWidth());
            }
            jugador = jugadorDerecha;
            jugador.update(delta);
        }
        if (entrada.isKeyDown(Input.KEY_LEFT)) {    // Tecla izquierda
            jugadorX -= delta * 0.1f;
            // evitar que nos salgamos por la izquierda del contenedor
            if (jugadorX < 0) {
                jugadorX = 0;
            }
            jugador = jugadorIzquierda;
            jugador.update(delta);
        }
       
      

        // NUEVO: Movemos los robots hacia el jugador si están vivos
       
        // cada 50 segundos, el robot se moverá un 50% más rápido
        // respecto a la velocidad inicial
        float prisa = 1.0f + (System.currentTimeMillis() - tiempo) / 50000.0f; // cuanto mayor sea, más rápido irán
        for (int i = 0; i < TOTAL_ROBOTS; i++) {
            if (robotVivo[i]) {
                // calculamos la escala del movimiento, pero la acotaremos
                // para que no sean demasiado rápidos o el jugador nunca
                // podría escapar
                float escalaFinal = prisa * 0.1f * robotVelocidad[i];
                escalaFinal = escalaFinal > 1.15 ? 1.15f : escalaFinal;
                if (robotY[i] > jugadorY) {
                    robotY[i] -= delta * escalaFinal;
                    robot[i] = robotArriba;
                }
                if (robotY[i] < jugadorY) {
                    robotY[i] += delta * escalaFinal;
                    robot[i] = robotAbajo;
                }
                if (robotX[i] > jugadorX) {
                    robotX[i] -= delta * escalaFinal;
                    robot[i] = robotIzquierda;
                }
                if (robotX[i] < jugadorX) {
                    robotX[i] += delta * escalaFinal;
                    robot[i] = robotDerecha;
                }
            } else {
                // si el robot está visible pero su animación se ha parado
                // es que acaba de termina la animación de la explosión,
                // así que lo ocultamos
                if ((robotVisible[i]) && (robot[i].isStopped())) {
                    robotVisible[i] = false;
                }
            }
        }
        // NUEVO: Comprobar si han chocado entre sí o con el jugador
        for (int i = 0; i < TOTAL_ROBOTS; i++) {
            if (robotVivo[i]) {
               
                // ¿Ha chocado el robot 'i' con el jugador?
                // Para nosotros habrán colisionado cuando
                // la parte izquierda de sus bases estén a menos de 4
                // píxeles en vertical y en horizontal
                if ((Math.abs(robotX[i] - jugadorX) < 4.0f)
                        && (Math.abs(robotY[i] - jugadorY) < 4.0f)) {
                   
                    // Sí: robot muerto
                    robotVivo[i] = false;

                    // Hacerlo explotar una sola vez
                    robot[i] = new Animation(explosion, 0, 0, 3, 3, true, 100, true);
                    robot[i].setLooping(false);

                    // Aunque no sirve de mucho, ¡un robot menos!
                    numeroRobotsVivos -= 1;
                   
                    // Reproducir explosión
                    sonido.play();
                   
                    // El jugador ha muerto
                    jugadorVivo = false;
                }
               
                // ¿Ha chocado el robot 'i' con otro robot?
                for (int j = 0; j < TOTAL_ROBOTS; j++) {
                    // Cuidado, hay que evita comprobar si hemos chocado con
                    // nosotros o nada más empezar explotaremos
                    if (i != j && robotVivo[j]) {
                        // Para nosotros habrán colisionado los robots cuando
                        // la parte izquierda de sus bases estén a menos de 4
                        // píxeles en vertical y en horizontal
                        if ((Math.abs(robotX[i] - robotX[j]) < 4.0f)
                                && (Math.abs(robotY[i] - robotY[j]) < 4.0f)) {
                           
                            // Sí: robots muertos
                            robotVivo[i] = false;
                            robotVivo[j] = false;

                            // Crear una nueva explosión y asignársela a los
                            // dos robots ya que explotan simultáneamente
                            robot[i] = new Animation(explosion, 0, 0, 3, 3, true, 100, true);
                            // Que sólo exploten una vez
                            robot[i].setLooping(false);
                            robot[j] = robot[i];

                            // Dos robots menos
                            numeroRobotsVivos -= 2;
                           
                            // Reproducir explosión
                            sonido.play();
                           
                            // Si ya no quedan robots, ¡hemos ganado!
                            if (numeroRobotsVivos == 100) {
                                // Cambiar música
                                musica = new Music("data/bi-menu.xm");
                                musica.loop();
                            }
                            // Esto es para evitar que un robot ya
                            // muerto destruya a otro
                            break;
                        }
                    }
                }
            }
        }
       
       
        if ((Math.abs((jugadorX+jugador.getWidth()) - (corazonX + corazon.getWidth())) < 13.0f)
                                && (Math.abs((jugadorY+jugador.getHeight()) - (corazonY+corazon.getHeight())) < 10.0f)) {
            numeroRobotsVivos=0;
        }
       
    }

    @Override
    public void render(GameContainer gc, Graphics g) throws SlickException {

        // dibujar tilemap
        mapa.render(0, 0);
       
        corazon.draw(corazonX,corazonY);

        // dibujar jugador. NUEVO: sólo si está vivo
        if (jugadorVivo == true) {
            jugador.draw(jugadorX, jugadorY);
        }

        // dibujar robots si están visibles
        for (int i = 0; i < TOTAL_ROBOTS; i++) {
            if (robotVisible[i]) {
                robot[i].draw(robotX[i], robotY[i]);
            }
        }

        // dibujar robots restantes
        fuente.drawString(400, 10, "Quedan " + numeroRobotsVivos + " robots");

        if (jugadorVivo == false) {
            String gameOver = "Fin de juego";
            // dibujamos el texto centrado en el contenedor
            fuente.drawString((gc.getWidth() - fuente.getWidth(gameOver)) / 2, (gc.getHeight() - fuente.getHeight(gameOver)) / 2, gameOver, Color.red);
            return;
        } else {
            if (numeroRobotsVivos == 0) {
                String gameOver = "¡Has ganado!";
                // dibujamos el texto centrado en el contenedor
                fuente.drawString((gc.getWidth() - fuente.getWidth(gameOver)) / 2, (gc.getHeight() - fuente.getHeight(gameOver)) / 2, gameOver, Color.yellow);

                return;
            }
        }

        // dibujar tiempo transcurrido si no ha acabado el juego
        fuente.drawString(40, 10, "Tiempo: " + (System.currentTimeMillis() - tiempo) / 1000);

    }
}