// DrawingGraph.java
package view2D;
import graph.Edge;
import graph.Vertex;
import java.awt.Color;
import java.awt.Graphics;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import javax.swing.ImageIcon;
import javax.swing.JOptionPane;
import labyrinth.grid.LabyrinthGrid;
import labyrinth.grid.Square;
import labyrinth.graph.LabyrinthGraph;
import labyrinth.graph.NoPathFoundException;
import labyrinth.graph.VertexRoom;
import character.Character;
import character.KeyboardCharacter;
/**
* Graph version of the Drawing class (with the brand-new enlightenment system :) )
* @author Adrien Sohier
* @author Matthias Devlamynck
*/
public class DrawingGraph extends Drawing {
private boolean isGraph;
private Collection<Square> shortestPath;
private ImageIcon roomPath;
/**
* Creates the drawing graph and populate the tree for finding shortest path
* @param labyrinth the game's labyrinth
* @param bob the main character
*/
public DrawingGraph(LabyrinthGrid labyrinth, Character bob, Collection<Character> characters)
{
super(labyrinth, bob, characters);
isGraph = (labyrinth instanceof LabyrinthGraph);
shortestPath = new ArrayList<Square>();
roomPath = new ImageIcon("icons/path.png");
warnUser = true;
}
/**
* Draw rooms, using the brand-new algorithm
* @param g the graphics to draw on
*/
public void drawRooms(Graphics g) {
if (!isGraph)
{
super.drawRooms(g);
return;
}
/*
* Rooms
*/
int r, c, distance = 0;
int distanceMax = 8;
Collection<VertexRoom> vr = new ArrayList<VertexRoom>();
Collection<VertexRoom> vr2 = new ArrayList<VertexRoom>();
Collection<VertexRoom> vr_light = new ArrayList<VertexRoom>();
Collection<Edge> eg = new ArrayList<Edge>();
vr.add((VertexRoom) bob.getLocation());
VertexRoom t, tve;
Iterator<VertexRoom> it_v;
Iterator<Edge> it_eg;
Edge te;
while (distance<distanceMax)
{
it_v = vr.iterator();
while (it_v.hasNext())
{
t = it_v.next();
vr_light.add(t);
eg = t.getEdges();
it_eg = eg.iterator();
while (it_eg.hasNext())
{
te = it_eg.next();
tve = (VertexRoom) te.getOtherVertex((Vertex) t);
if (!vr_light.contains(tve))
vr2.add(tve);
}
r = ((Square) t).getRow();
c = ((Square) t).getColumn();
if (((KeyboardCharacter) bob).lightIsOn())
{
t.setLight(distanceMax-distance-1);
g.drawImage(roomIcons[t.getLight()].getImage(), c*unite, r*unite, null);
if(t.isThereKey())
g.drawImage(key.getImage(), c * unite, r * unite, null);
}
else
t.setLight(0);
}
vr.clear();
vr.addAll(vr2);
vr2.clear();
distance++;
}
}
/**
* Draw the shortest path and updates it at every move
* @param g the graphics to draw on
*/
public void drawExitPath(Graphics g)
{
// Draw the path.
g.setColor(new Color(64, 16, 128));
for(Square s : shortestPath)
g.drawImage(roomPath.getImage(), ((VertexRoom) s).getColumn()*unite, ((VertexRoom) s).getRow()*unite, null);
}
/**
* Draw everything
* @param g the graphics to draw on
*/
public void paintComponent(Graphics g) {
drawBackground(g);
drawVisitedRooms(g);
drawRooms(g);
if (isGraph && drawHint)
drawExitPath(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
*/
public void updatePathtoExit() throws RestartLevelException, AbortGameException {
JOptionPane msg = new JOptionPane();
if (drawHint)
shortestPath.clear();
try
{
shortestPath.addAll(((LabyrinthGraph)maze).getShortestPathToExit(bob));
}
catch(NoPathFoundException e)
{
if (warnUser)
{
msg.showMessageDialog(this, "Je suis désolé, mais vous n'avez plus suffisamment de vie pour continuer.\nVous allez mourir ici...", "Mauvaise nouvelle", JOptionPane.WARNING_MESSAGE);
int ans = msg.showOptionDialog(this, "Voulez-vous recommencer ?", "Redémarrer le niveau", JOptionPane.YES_NO_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE, null, null, null);
switch(ans)
{
case 0:
throw(new RestartLevelException());
case 1:
throw(new AbortGameException());
case 2:
msg.showMessageDialog(this, "Vous voulez donc continuer, soit.\nMais vous allez mourir sans voir la sortie...");
warnUser = false;
default:
break;
}
}
}
}
/**
* Set if the hint will be drawn or not.
* @param hint The state of drawHint.
*/
public void setDrawtHint(boolean hint) {
super.setDrawtHint(hint);
if(drawHint == false && hint == true)
try {
this.updatePathtoExit();
} catch (RestartLevelException rge) {
System.out.println("Caught Restart Level Exception.");
} catch (AbortGameException age) {
System.out.println("Caught Abort Game Exception.");
}
}
}