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; private boolean isGrowing; private int count; /** * 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) // Display the caterpillar (call a private method) displayCaterpillar(); } /** * 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) { // Is the move illegal? boolean isMoveNotOK; // newDir might not be legal // Before trying a random direction, try first // the current direction of motion (if not newDir) boolean isFirstTry = true; // move the caterpillar in direction newDir do { // new position of the head Point head = new Point((Point) body.get(body.size() - 1)); switch (newDir) { case NORTH: head.y -= STEP; break; case SOUTH: head.y += STEP; break; case EAST: head.x += STEP; break; case WEST: head.x -= STEP; break; } // Is the new position in the window? if (isPointInTheWindow(head)) { isMoveNotOK = false; // Update the position of the caterpillar if (!isGrowing) { body.remove(0); } body.add(head); } else { isMoveNotOK = true; // Select another direction // Try the current direction first if (newDir != dir && isFirstTry) { newDir = dir; isFirstTry = false; } else // random direction newDir = (int) (Math.random() * 4 + 1); } } while (isMoveNotOK); // Update the current direction of motion dir = newDir; // Show the new location of the caterpillar moveCaterpillarOnScreen(); } /** * Move the caterpillar on the screen */ private void moveCaterpillarOnScreen() { // Erase the body unit at the tail if (!isGrowing) { window.remove((Shape) bodyUnits.get(0)); bodyUnits.remove(0); } else { count--; isGrowing = (count >= 1); } // Add a new body unit at the head Point q = (Point) body.get(body.size() - 1); Point p = (Point) body.get(body.size() - 2); createBodyUnit(p, q, bodyUnits.size()); window.add((Rectangle) bodyUnits.get(bodyUnits.size() - 1)); // show it window.doRepaint(); } /** * Is Point p in the window? */ private boolean isPointInTheWindow(Point p) { return (p.x >= 0 && p.x <= WINDOW_WIDTH && p.y >= 0 && p.y <= WINDOW_HEIGHT); } /** * 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() { isGrowing = true; count = 5; // // location of the tail // Point p = (Point) body.get(0); // Point q = (Point) body.get(1); // // grow the caterpillar by 5 body units // // Add points // for (int i = 0; i < 5; i++) { // Point r = new Point(); // r.x = 2 * p.x - q.x; // r.y = 2 * p.y - q.y; // body.add(0, r); // createBodyUnit(p, r, 0); // window.add((Rectangle) bodyUnits.get(0)); // q = p; // p = r; // } } /** * Displays the caterpillar */ private void displayCaterpillar() { Point p = (Point) body.get(0); for (int i = 1; i < body.size(); i++) { Point q = (Point) body.get(i); // draw a rectangle between p and q createBodyUnit(p, q, bodyUnits.size()); p = q; } for (Object obj : bodyUnits) { Rectangle r = (Rectangle) obj; window.add(r); } } private void createBodyUnit(Point p, Point q, int index) { if (p.y == q.y) { // horizontal body unit Rectangle r = new Rectangle(Math.min(p.x, q.x), p.y - CATERPILLAR_WIDTH / 2, STEP, CATERPILLAR_WIDTH, Color.RED, true); bodyUnits.add(index, r); } else { // vertical Rectangle r = new Rectangle(p.x - CATERPILLAR_WIDTH / 2, Math.min( p.y, q.y), CATERPILLAR_WIDTH, STEP, Color.RED, true); bodyUnits.add(index, r); } } }