Lamentablemente para nuestro personaje tenemos que agregar algunas trampas en el camino, para que no sea tan sencillo. Comenzaremos incorporando fuego.
![](https://www.gsampallo.com/blog/wp-content/uploads/2020/05/On-16x32.png)
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.