// Drawing.java
package view2D;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.event.KeyListener;
import java.util.ArrayList;
import java.util.Collection;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JLabel;
import view2D.ButtonMovementListener;
import character.DefaultCharacter;
import character.KeyboardCharacter;
import character.Character;
import labyrinth.Room;
import labyrinth.graph.VertexRoom;
import labyrinth.grid.LabyrinthGrid;
import labyrinth.grid.Square;
import labyrinth.grid.utils.Utils;
/**
* Class for drawing user interface
* @author Matthias Devlamynck
* @author Adrien Sohier
*/
public class Drawing extends JComponent {
public static final int unite = 15;
protected LabyrinthGrid maze;
protected Collection<Character> characters;
protected Character bob;
protected int buttonWidth = 57, buttonHeight = 46;
protected int hudWidth = buttonWidth * 3;
protected int minHeight = 4 * buttonHeight;
protected Square entrance;
protected Square exit;
protected ArrayList<Square> visitedRooms = new ArrayList<Square>();
protected ArrayList<Square> visitedTrappedRooms = new ArrayList<Square>();
protected boolean drawHint = false;
protected JButton bLeft, bRight, bUp, bDown;
protected JButton help;
protected JLabel life;
protected float animationCounter = 0;
protected int animCycles=0;
protected ImageIcon anim[], roomIcons[], roomStart, roomEnd, triggeredRoom;
protected ImageIcon key;
protected int remainingHints = 3;
protected int distanceMax = 8;
protected boolean warnUser;
/**
* Draw labyrinth and character
* @param labyrinth The labyrinth to draw
* @param bob The character to draw
*/
public Drawing(LabyrinthGrid labyrinth, Character bob, Collection<Character> characters) {
this.maze = labyrinth;
entrance = (Square) labyrinth.getEntrance();
exit = (Square) labyrinth.getExit();
this.bob = bob;
this.characters = characters;
if(labyrinth.getHeight() * unite < minHeight)
setPreferredSize(new Dimension(labyrinth.getWidth() * unite + hudWidth, minHeight));
else
setPreferredSize(new Dimension(labyrinth.getWidth() * unite + hudWidth, labyrinth.getHeight() * unite));
/*
* add key listened on the draw's attached keyboard
*/
addKeyListener((KeyListener) bob);
/*
* Creation of the buttons
*/
// Instantiate
bLeft = new JButton(new ImageIcon("icons/left.gif"));
bRight = new JButton(new ImageIcon("icons/right.gif"));
bUp = new JButton(new ImageIcon("icons/forward.gif"));
bDown = new JButton(new ImageIcon("icons/back.gif"));
help = new JButton("Hint " + remainingHints);
// Add to the container.
add(bLeft);
add(bRight);
add(bUp);
add(bDown);
add(help);
// Defining location and size of the buttons.
bLeft.setBounds(labyrinth.getWidth() * unite, labyrinth.getHeight() * unite / 2 + buttonHeight / 2, buttonWidth, buttonHeight);
bRight.setBounds(labyrinth.getWidth()*unite + 2 * buttonWidth, labyrinth.getHeight() * unite / 2 + buttonHeight / 2, buttonWidth, buttonHeight);
bDown.setBounds(labyrinth.getWidth()*unite + buttonWidth, labyrinth.getHeight() * unite / 2 + buttonHeight / 2, buttonWidth, buttonHeight);
bUp.setBounds(labyrinth.getWidth()*unite + buttonWidth, labyrinth.getHeight() * unite / 2 - buttonHeight / 2, buttonWidth, buttonHeight);
help.setBounds(labyrinth.getWidth()*unite, labyrinth.getHeight() * unite / 2 + 3 * buttonHeight / 2, hudWidth, buttonHeight);
// Removing focus from the buttons or keyboard wont work.
bLeft.setFocusable(false);
bRight.setFocusable(false);
bUp.setFocusable(false);
bDown.setFocusable(false);
help.setFocusable(false);
// Instantiate the listeners.
bLeft.addActionListener(new ButtonMovementListener(ButtonMovementListener.Direction.gauche, labyrinth, bob));
bRight.addActionListener(new ButtonMovementListener(ButtonMovementListener.Direction.droite, labyrinth, bob));
bUp.addActionListener(new ButtonMovementListener(ButtonMovementListener.Direction.haut, labyrinth, bob));
bDown.addActionListener(new ButtonMovementListener(ButtonMovementListener.Direction.bas, labyrinth, bob));
help.addActionListener(new ButtonHintListener(this));
// Infos on player.
life = new JLabel(bob.getLife() + "%");
add(life);
life.setBounds(labyrinth.getWidth() * unite + 50, 5, 100, 50);
anim = new ImageIcon[3];
anim[0] = new ImageIcon("icons/wephit.gif");
anim[1] = new ImageIcon("icons/wephit2.gif");
anim[2] = new ImageIcon("icons/wephit3.gif");
key = new ImageIcon("icons/key.png");
roomIcons = new ImageIcon[distanceMax];
for (int i=0 ; i<distanceMax ; i++)
roomIcons[i] = new ImageIcon("icons/rooms/room"+i+".png");
roomStart = new ImageIcon("icons/rooms/room_start.gif");
triggeredRoom = new ImageIcon("icons/triggered.png");
roomEnd = new ImageIcon("icons/rooms/room_end.gif");
}
/**
* Draw background of the screen
* @param g the graphics to use
*/
public void drawBackground(Graphics g) {
/*
* Black window background
*/
g.setColor(Color.black);
g.fillRect(0, 0, maze.getWidth() * unite, maze.getHeight() * unite);
}
/**
* Draw rooms
* @param g the graphics to draw on
*/
public void drawRooms(Graphics g) {
/*
* Rooms
*/
Collection<Room> rooms = maze.getRooms();
int r, c, distance = 0;
for (Room s : rooms) {
distance = Utils.distance((Square) bob.getLocation(), (Square) s);
if (distance <= distanceMax) {
r = ((Square) s).getRow();
c = ((Square) s).getColumn();
if (((KeyboardCharacter) bob).lightIsOn())
{
s.setLight(distanceMax-distance-1);
g.drawImage(roomIcons[s.getLight()].getImage(), c*unite, r*unite, null);
if(s.isThereKey())
g.drawImage(key.getImage(), c * unite, r * unite, null);
}
else
s.setLight(0);
}
}
}
/**
* Draw viewed rooms
* @param g the graphics to draw on
*/
public void drawVisitedRooms(Graphics g) {
/*
* Drawing known rooms
*/
Square c = (Square) bob.getLocation();
if (!visitedRooms.contains(c)) // updating visited rooms
visitedRooms.add(c);
for (Square s : visitedRooms) {
int j = s.getColumn();
int i = s.getRow();
g.drawImage(roomIcons[0].getImage(), j * unite, i * unite, null);
}
}
/**
* Draw viewed trapped rooms
* @param g The graphic to draw on
*/
public void drawVisitedTrappedRoom(Graphics g)
{
int i, j;
for(Square s : visitedTrappedRooms)
{
i = s.getColumn();
j = s.getRow();
/*g.setColor(Color.red);
g.drawLine(i*unite, j*unite, i*unite + unite - 1, j*unite + unite);
g.drawLine(i*unite, j*unite + unite, i*unite + unite - 1, j*unite);*/
g.drawImage(triggeredRoom.getImage(), i*unite, j*unite, null);
}
}
/**
* Draw entrance and exit rooms
* @param g the graphics to draw on
*/
public void drawnEntranceExit(Graphics g) {
g.drawImage(roomStart.getImage(), entrance.getColumn() * unite, entrance.getRow() * unite, null);
g.drawImage(roomEnd.getImage(), exit.getColumn() * unite, exit.getRow() * unite, null);
}
/**
* Draw every characters.
* @param g the graphics to draw on
*/
public void drawCharacters(Graphics g) {
ImageIcon c_image;
DefaultCharacter c_char;
for(Character c : characters)
{
c_char = (DefaultCharacter) c;
c_image = c_char.updatePos();
g.drawImage(c_image.getImage(), (int) c_char.locX(), (int) c_char.locY(), null);
}
}
/**
* Draw the right image of the animation.
* @param g the graphics to draw on.
*/
public void playAnim(Graphics g)
{
int image, w, h;
if(animationCounter > 3.f)
image = 2;
else if(animationCounter > 2.f)
image = 1;
else if(animationCounter > 1.f)
image = 0;
else
image = 1;
w = anim[image].getIconWidth();
h = anim[image].getIconHeight();
g.drawImage(anim[image].getImage(), ((Square) bob.getLocation()).getColumn()*unite-(w/2), ((Square) bob.getLocation()).getRow()*unite-(h/2), null);
animationCounter-=0.2f;
if ((animationCounter<=0.f) && (animCycles>0))
{
animationCounter = 4.f;
animCycles--;
}
}
/**
* Draw everything
* @param g the graphics to draw on
*/
public void paintComponent(Graphics g) {
drawBackground(g);
drawVisitedRooms(g);
drawRooms(g);
drawnEntranceExit(g);
drawVisitedTrappedRoom(g);
drawCharacters(g);
if(animationCounter > 0)
playAnim(g);
}
/**
* Update the path to the exit. Must be called when the character moved.
* @throws RestartLevelException
* @throws AbortGameException
*/
public void updatePathtoExit() throws RestartLevelException, AbortGameException {
}
/**
* Add the current room to the triggered trapped room if it is trapped.
*/
public void updateTraps() {
Square c = (Square) bob.getLocation();
if ((!visitedTrappedRooms.contains(c)) &&
((VertexRoom) c).getDamage()>0)
{
// Add the room.
visitedTrappedRooms.add(c);
// Play the animation.
animationCounter = 4.f;
animCycles = 1;
}
}
/**
* Update the label showing the character's life.
*/
public void updateLife() {
life.setText(bob.getLife() + "%");
}
/**
* Get the drawHint state.
* @return True if the hint is drawn false if not.
*/
public boolean getDrawHint() {
return drawHint;
}
/**
* Set if the hint will be drawn or not.
* @param hint The state of drawHint.
*/
public void setDrawtHint(boolean hint) {
if(drawHint == false && hint == true)
{
remainingHints--;
if(remainingHints <= 0)
help.setText("No more hints");
else
help.setText("Hint " + remainingHints);
}
if(remainingHints >= 0)
drawHint = hint;
}
}