import uwcse.graphics.*; import java.awt.Point; import java.util.*; import java.awt.Color; /** * A Caterpillar is the representation and the display of a caterpillar */ public class Caterpillar implements CaterpillarGameConstants { // The body of a caterpillar is made of Points stored // in an ArrayList private ArrayList body = new ArrayList(); // Store the graphical elements of the caterpillar body // Useful to erase the body of the caterpillar on the screen private ArrayList bodyUnits = new ArrayList(); // The window the caterpillar belongs to private GWindow window; // Direction of motion of the caterpillar (NORTH initially) private int dir = NORTH; /** * Constructs a caterpillar * * @param window * the graphics where to draw the caterpillar. */ public Caterpillar(GWindow window) { // Initialize the graphics window for this Caterpillar this.window = window; // Create the caterpillar (10 points initially) // First point Point p = new Point(); p.x = 5; p.y = WINDOW_HEIGHT / 2; body.add(p); // Other points for (int i = 0; i < 9; i++) { Point q = new Point(p); q.translate(STEP, 0); body.add(q); p = q; } // Other initializations (if you have more instance fields) for (int i = 0; i < body.size() - 1; i++) { Point p1 = (Point) body.get(i); Point p2 = (Point) body.get(i + 1); // Create a body unit between p1 and p2 createBodyUnit(p1, p2); } // Display the caterpillar for (Object obj : bodyUnits) { Shape s = (Shape) obj; window.add(s); } } /** * Moves the caterpillar in the current direction (complete) */ public void move() { move(dir); } /** * Move the caterpillar in the direction newDir.
* If the new direction is illegal, select randomly a legal direction of * motion and move in that direction.
* * @param newDir * the new direction. */ public void move(int newDir) { Point head = (Point) body.get(body.size() - 1); Point p; do { p = new Point(head); // new location of the head switch (newDir) { case NORTH: p.y -= STEP; break; case SOUTH: p.y += STEP; break; case EAST: p.x += STEP; break; case WEST: p.x -= STEP; break; } if (!isInWindow(p)) { // select a new direction // try the current direction first if different if (newDir != dir) { newDir = dir; } else { // random int[] directions = { NORTH, WEST, SOUTH, EAST }; newDir = directions[(int) (Math.random() * 4)]; } } } while (!isInWindow(p)); dir = newDir; body.add(p); createBodyUnit(p, head); window.add((Shape) bodyUnits.get(bodyUnits.size() - 1)); // remove the tail point body.remove(0); Shape s = (Shape) bodyUnits.remove(0); window.remove(s); } /** * Is the caterpillar crawling over itself? * * @return true if the caterpillar is crawling over itself and false * otherwise. */ public boolean isCrawlingOverItself() { // Is the head point equal to any other point of the caterpillar? return false; // CHANGE THIS! } /** * Are all of the points of the caterpillar outside the garden * * @return true if the caterpillar is outside the garden and false * otherwise. */ public boolean isOutsideGarden() { return false; // CHANGE THIS! } /** * Return the location of the head of the caterpillar (complete) * * @return the location of the head of the caterpillar. */ public Point getHead() { return new Point((Point) body.get(body.size() - 1)); } /** * Increase the length of the caterpillar (by GROWTH_SPURT elements) Add the * elements at the tail of the caterpillar. */ public void grow() { // Get the direction of the first segment of the caterpillar Point p = (Point) body.get(0); Point q = (Point) body.get(1); int deltaX = q.x - p.x; int deltaY = q.y - p.y; for (int i = 1; i < GROWTH_SPURT; i++) { q = new Point(p); // copy of the tail point // Translate the point in the opposite direction of the first // segment of the caterpillar q.x -= deltaX; q.y -= deltaY; body.add(0, q); createBodyUnit(q, p); p = q; } } /** * Creates a rectangle between p1 and p2 */ private void createBodyUnit(Point p1, Point p2) { if (p1.x == p2.x) { // vertical rectangle int x = p1.x - CATERPILLAR_WIDTH / 2; int y = Math.min(p1.y, p2.y) - CATERPILLAR_WIDTH / 2; Rectangle r = new Rectangle(x, y, CATERPILLAR_WIDTH, STEP + CATERPILLAR_WIDTH, Color.RED, true); bodyUnits.add(r); } else { // horizontal rectangle int x = Math.min(p1.x, p2.x) - CATERPILLAR_WIDTH / 2; int y = p1.y - CATERPILLAR_WIDTH / 2; Rectangle r = new Rectangle(x, y, STEP + CATERPILLAR_WIDTH, CATERPILLAR_WIDTH, Color.RED, true); bodyUnits.add(r); } } // Is the point in the window? private boolean isInWindow(Point p) { return p.x >= 0 && p.x <= window.getWindowWidth() && p.y >= 0 && p.y <= window.getWindowHeight(); } }