/* Name: Chris Johnson johnson@dcs.gla.ac.uk Last modified: 5/1/99 Description: This class implements a maze canvas - it draws a boundary wall that is indented from the edge of the canvas. It also draws a number of internal walls and a drone whose position within the maze is given by X and Y values. MazeCanvas is the principle constructor for the class. paint() simply draws the maze canvas and does NOT alter the position of the drone. Internal Note: this includes a call to draw_walls which calculates the position of the walls relative to the size of the canvas. This is important because the walls will still appear in the correct positions still appear in the correct positions even if the applet is resized at any stage. update(newX, newY) alters the position of the drone in the maze and then re-paints the maze with this new position. Internal Note: this calls check_dimensions which checks first to see if the drone's movement will cross ouside of the maze's boundary walls. It also checks for any collision against internal walls. Restrictions and extensions: The data structure that is used to represent the maze walls is extremely crude, as are the maze drawing and collision detection algorithms. */ import java.awt.*; class MazeCanvas extends Canvas { static final int drone_size=15; static final int canvas_indent=5; private int X, Y; private MazeExample parent; MazeCanvas (MazeExample owner) { super(); parent = owner; X = Y = canvas_indent; } public void update(int newX, int newY) // check for any collisions with the walls or the boundary of the canvas // then redraw the maze with the drones position updated. { check_dimensions(newX, newY); repaint(); } public void paint(Graphics canvasG) { Dimension d = new Dimension(size()); // First draw two rectangles around the border of the canvas. // They are slightly indented so the user can see the edge of the maze. // Draw a rectangle one pixel outside that of the actual canvas border canvasG.drawRect(canvas_indent-2, canvas_indent-2, d.width-(canvas_indent+1), d.height-(canvas_indent+1)); // Draw a rectangle to show the canvas edge with a slight indent canvasG.drawRect(canvas_indent, canvas_indent, d.width-canvas_indent*2, d.height-canvas_indent*2); // next draw the walls inside the border draw_walls(canvasG); // finally draw the drone in its (X,Y) position canvasG.fillRect(X, Y, drone_size, drone_size); } private void check_dimensions(int newX, int newY) // only update the position of the drone if it's new position will be inside // the boundary of the canvas AND the drone will not collide with any of // the maze walls. { if (in_bounds(newX, newY) && in_walls(newX, newY)) { X = X + newX; Y = Y + newY; } } private boolean in_bounds(int newX, int newY) // is true if the new position of the drone is inside the maze boundary { Dimension d = new Dimension(size()); if ((X + newX >= canvas_indent) && (X+newX+drone_size <= d.width-(canvas_indent)) && (Y + newY >= canvas_indent) && (Y+newY+drone_size <= d.height-(canvas_indent))) return true; else return false; } private boolean in_walls(int newX, int newY) // is true if the new position of the drone does not cross any of the existing walls { Dimension d = new Dimension(size()); if((check_wall(newX, newY, canvas_indent+d.width/4, canvas_indent, canvas_indent+d.width/4, canvas_indent+d.height/4) && check_wall(newX, newY, canvas_indent, canvas_indent+d.height/4, canvas_indent+d.width/4-drone_size*2,canvas_indent+d.height/4) && check_wall(newX, newY, canvas_indent, canvas_indent+d.height/2, canvas_indent*4, canvas_indent+d.height/2) && check_wall(newX, newY, canvas_indent*4+drone_size*2, canvas_indent+d.height/2, canvas_indent+d.width/2, canvas_indent+d.height/2) && check_wall(newX, newY, canvas_indent+d.width/2, canvas_indent+d.height/2, canvas_indent+d.width/2, canvas_indent) && check_wall(newX, newY, canvas_indent, canvas_indent+d.height*3/4, canvas_indent+d.width*3/4, canvas_indent+d.height*3/4) && check_wall(newX, newY, canvas_indent+d.width*3/4, canvas_indent+d.height*3/4, canvas_indent+d.width*3/4, canvas_indent+drone_size*2))) return true; else return false; } private boolean check_wall(int newX, int newY, int X1, int Y1,int X2, int Y2) // checks to see if the drone will collide with a particular wall { if ((X1==X2) && (X + newX + drone_size > X1) && (X + newX < X1) && (Y + newY < max(Y1,Y2))&& (Y + newY + drone_size >= min(Y1, Y2))) return false; else if ((Y1==Y2) && (Y + newY + drone_size > Y1) && (Y + newY < Y1) && (X + newX < max(X1, X2))&& (X + newX + drone_size >= min(X1, X2))) return false; else return true; } private int max(int v1, int v2) { if (v1