Juego de plataformas en Java (10): Trampas

Lamentablemente para nuestro personaje tenemos que agregar algunas trampas en el camino, para que no sea tan sencillo. Comenzaremos incorporando fuego.

Como existen diferentes tipos de trampas disponibles en la galería de imágenes, y quiero mantener la estructura del juego mas o menos similar; crearemos una clase llamada Trap que implementa Element de la siguiente forma:

package gsampallo.traps;

import java.awt.Point;
import java.awt.image.BufferedImage;

import gsampallo.Element;

public class Trap implements Element {

    public static int FIRE = 0;

    protected int width;
    protected int height;

    protected int trapType = 0;
    protected Point position;
    protected boolean visible = true;

    protected boolean on = true;


    public Trap(int type,Point initialPoint) {
        this.trapType = type;
        this.position = initialPoint;
    }

    /**
     * @return the trapType
     */
    public int getTrapType() {
        return trapType;
    }

    @Override
    public int getX() {
        return position.x;
    }

    @Override
    public int getY() {
        return position.y;
    }

    @Override
    public int getWidth() {
        return width;
    }

    @Override
    public int getHeight() {
        return height;
    }

    @Override
    public boolean isVisible() {
        return visible;
    }

    @Override
    public BufferedImage getImage() {
        // TODO Auto-generated method stub
        return null;
    }

    public void updateTrap(boolean move) {
        return;
    }

    public boolean isOn() {
        return on;
    }

    public void setOn(boolean isOn) {
        this.on = isOn;
    }

}

Incorporamos una variable boolean llamada on; nos permite saber si la trampa esta activa o no; a partir de ello podremos determinar que imagen devolveremos y si hace daño al jugador o no.

Cada tipo de trampa extenderá de la clase Trap, especializándose en la forma en que trabaja. Crearemos la clase Fire:

package gsampallo.traps;

import java.awt.Point;
import java.awt.image.BufferedImage;
import java.io.File;

import javax.imageio.ImageIO;

public class Fire extends Trap {

    private boolean on = true;

    public Fire(int type, Point initialPoint) {
        super(type, initialPoint);

        this.width = 16;
        this.height = 32;

        loadImages();

    }

    private BufferedImage imageOff;
    private BufferedImage imageOn;

    private void loadImages() {

        try {

            imageOff = ImageIO.read(new File("image/Traps/Fire/Off.png"));
            imageOn = ImageIO.read(new File("image/Traps/Fire/On (16x32).png"));

        } catch (Exception e) {
            System.err.println("No se pudieron cargar imagenes de Fire");
            System.err.println(e.getMessage());
        }
    }

Hasta acá es más o menos lo que veníamos trabajando, cambiamos el nombre del package, en esta oportunidad esta dentro de traps; de esa forma podemos comenzar a agrupar las clases y organizamos un poco.

El metodo updateTrap(boolean) debe no solo actualizar el indice de la imagen que se va a devolver, para el caso que este encendido, sino que también debe llevar un segundo ciclo para saber cuanto tiempo mostraremos la trampa apagada.

    private int imageNumber = 0;
    private int firePeriodOn = 6;
    private int firePeriodOff = 9;
    private int firePeriodNumber = 0;

    public void updateTrap(boolean move) {

        if(on) {

            if(firePeriodNumber < firePeriodOn) {
                if(imageNumber < (imageOn.getWidth()/width)-1) {
                    imageNumber++;
                } else {
                    imageNumber = 0;
                    firePeriodNumber++;
                }
            } else {
                on = false;
                imageNumber = 0;
                firePeriodNumber = 0;
            }


        } else {

            if(imageNumber < firePeriodOff) {
                imageNumber++;
            } else {
                
                //Cicle complete, change period number
                firePeriodNumber = 0;
                imageNumber = 0;
                on = true;

            }

        }

        if(move) {
            position.x--;
            visible = (position.x > 0);
        }

    }

    public BufferedImage getImage() {
        if(on) {
            int x = imageNumber*width;
            return imageOn.getSubimage(x,0,width,height);
        } else {
            return imageOff;
        }
    }

Modificando las variables firePeriodOn y firePeriodOff; podemos alterar el tiempo que se encuentran encendidos o apagadas cada una de las trampas. Incorporaremos dos métodos para poder hacerlo:

    public void setPeriodFireOn(int period) {
        this.firePeriodOn = period;
    }
    
    public void setPeriodFireOff(int period) {
        this.firePeriodOff = period;
    }

De igual manera que lo hicimos con las Box y Fruit, crearemos un arrayList para poder llevar el control de las Traps:

private ArrayList<Trap> listTraps;

public RunnerOne() {
  /** resto del codigo **/
  Fire fire = new Fire(Trap.FIRE,new Point(270,410));

  listTraps = new ArrayList<Trap>();
  listTraps.add(fire);  

}

Modificaremos el método paint() de la misma manera:

public void paint(Graphics g) {

  /** resto del codigo **/
  drawList(listTraps, g);

}

Incorporamos el bloque de código siguiente en updateGame() para actualizar nuestras trampas:

public void updateGame() {
  /** resto del codigo **/
  if(!listTraps.isEmpty()) {
    Iterator it = listTraps.iterator();
    while(it.hasNext()) {
      Trap trap = (Trap)it.next();

      trap.updateTrap(moved);
      if(!trap.isVisible()) {        
        it.remove();
      }
    }
  }
}

Si compilamos y ejecutamos obtendremos el siguiente resultado:

<insertar gif>

Nos queda incorporar el daño que causa las trampas a nuestro jugador, esto lo realizaremos más adelante.

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *