/*
Copyright 2009 by Sean Luke and Vittorio Zipparo
Licensed under the Academic Free License version 3.0
See the file "LICENSE" for more information
*/
package sim.app.pacman;
import java.awt.*;
import sim.field.grid.*;
import sim.portrayal.*;
import sim.portrayal.grid.*;
import java.awt.geom.*;
import sim.util.*;
/**
A special portrayal for drawing part of the maze. The way this portion
is drawn (as a curved or straight line) depends in part on neighboring
parts of the maze, making the portrayal a bit more complex. We use the
new *location* field in DrawInfo2D to determine where we are in the maze,
and hence what our neighbors are. Drawing is then done using Java2D
operators.
*/
public class MazeCellPortrayal extends SimplePortrayal2D
{
private static final long serialVersionUID = 1;
IntGrid2D field;
public MazeCellPortrayal(IntGrid2D field) { this.field = field; }
QuadCurve2D.Double curve = new QuadCurve2D.Double();
Line2D.Double line = new Line2D.Double();
Color color = new Color(33,33,222); // traditional pacman color
BasicStroke stroke = new BasicStroke(2f);
public void draw(Object object, Graphics2D g, DrawInfo2D info)
{
int[][] grid = field.field;
MutableInt2D location = (MutableInt2D)(info.location);
int x = location.x;
int y = location.y;
double ox = info.draw.x;
double oy = info.draw.y;
double sc = info.draw.width / 2;
// only certain grid patterns are allowed in PacMan
//
// O O O X X X X X X
// O OXX XXO XXX OXX XXO XXX XXO OXX XXX
// X X X O O O X X X
//
// ... where X = wall, O = open, space = don't care.
// That is, if there is an O on one side, there MUST be
// an X on the other side. Except when the object itself is an O.
//
// There are also inside curves:
//
// OX XO
// XX XX XX XX
// OX XO
//
// We identify which patern you have:
if ((int)(((MutableDouble)object).val) == 0) // we're open
{
return;
}
else // we're a wall. Need to draw
{
// get the N/S/E/W values
int height = field.getHeight() - 1;
int width = field.getWidth() - 1;
int n = (y == 0 ? 1 : grid[x][y-1]);
int w = (x == 0 ? 1 : grid[x-1][y]);
int s = (y == height ? 1 : grid[x][y+1]);
int e = (x == width ? 1 : grid[x+1][y]);
g.setColor(color);
g.setStroke(stroke);
if (n == 0)
{
if (w == 0)
{
curve.setCurve(ox + sc, oy, ox, oy, ox, oy + sc); // curve left to up
g.draw(curve);
}
else if (e == 0)
{
curve.setCurve(ox - sc, oy, ox, oy, ox, oy + sc); // curve right to up
g.draw(curve);
}
else // neither
{
line.setLine(ox + sc, oy, ox - sc, oy); // horizontal line
g.draw(line);
}
}
else if (s == 0)
{
if (w == 0)
{
curve.setCurve(ox + sc, oy, ox, oy, ox, oy - sc); // curve left to down
g.draw(curve);
}
else if (e == 0)
{
curve.setCurve(ox - sc, oy, ox, oy, ox, oy - sc); // curve right to down
g.draw(curve);
}
else // neither
{
line.setLine(ox + sc, oy, ox - sc, oy); // horizontal line
g.draw(line);
}
}
else if (e == 0)
{
line.setLine(ox, oy + sc, ox, oy - sc); // vertical line
g.draw(line);
}
else if (w == 0)
{
line.setLine(ox, oy + sc, ox, oy - sc); // vertical line
g.draw(line);
}
else // perhaps an inside curve?
{
int nw = (y == 0 || x == 0 ? 1 : grid[x-1][y-1]);
int sw = (y == height || x == 0 ? 1 : grid[x-1][y+1]);
int ne = (y == 0 || x == width ? 1 : grid[x+1][y-1]);
int se = (y == height || x == width ? 1 : grid[x+1][y+1]);
if (nw == 0)
{
curve.setCurve(ox - sc, oy, ox, oy, ox, oy - sc);
g.draw(curve);
}
else if (sw == 0)
{
curve.setCurve(ox - sc, oy, ox, oy, ox, oy + sc);
g.draw(curve);
}
else if (ne == 0)
{
curve.setCurve(ox + sc, oy, ox, oy, ox, oy - sc);
g.draw(curve);
}
else if (se == 0)
{
curve.setCurve(ox + sc, oy, ox, oy, ox, oy + sc);
g.draw(curve);
}
else
{
// nada
}
}
}
}
}