import java.util.Random; import tester.*; import idraw.*; import geometry.*; import colors.*; /** * Copyright 2008 Viera K. Proulx * This program is distributed under the terms of the * GNU Lesser General Public License (LGPL) */ /** Class that represents a colored disk that moves around the Canvas */ class Blob{ Posn center; int radius; IColor col; /** The constructor */ Blob(Posn center, int radius, IColor col) { this.center = center; this.radius = radius; this.col = col; } /** draw this blob in the given World */ void draw(Canvas c) { c.drawDisk(this.center, this.radius, col); } /** move this blob 20 pixels in the direction given by the ke or change its color to Green, Red or Yellow */ public void moveBlob(String ke){ if (ke.equals("right")){ this.center = new Posn(this.center.x + 5, this.center.y); } else if (ke.equals("left")){ this.center = new Posn(this.center.x - 5, this.center.y); } else if (ke.equals("up")){ this.center = new Posn(this.center.x, this.center.y - 5); } else if (ke.equals("down")){ this.center = new Posn(this.center.x, this.center.y + 5); } // change the color to Y, G, R else if (ke.equals("Y")){ this.col = new Yellow(); } else if (ke.equals("G")){ this.col = new Green(); } else if (ke.equals("R")){ this.col = new Red(); } } /** produce a new blob moved by a random distance < n pixels */ void randomMove(int n){ this.center = new Posn(this.center.x + this.randomInt(n), this.center.y + this.randomInt(n)); } /** helper method to generate a random number in the range -n to n */ int randomInt(int n){ return -n + (new Random().nextInt(2 * n + 1)); } /** is the blob outside the bounds given by the width and height */ boolean outsideBounds(int width, int height) { return this.center.x < 0 || this.center.x > width || this.center.y < 0 || this.center.y > height; } /** is the blob near the center of area given by the width and height */ boolean nearCenter(int width, int height) { return this.center.x > width / 2 - 10 && this.center.x < width / 2 + 10 && this.center.y > height / 2 - 10 && this.center.y < height / 2 + 10; } } /** Represent the world of a Blob */ class BlobWorld extends World { int width = 200; int height = 300; Blob blob; /** The constructor */ public BlobWorld(Blob blob) { super(); this.blob = blob; } /** Move the Blob when the player presses a key */ public void onKeyEvent(String ke) { this.blob.moveBlob(ke); } /** On tick check whether the Blob is out of bounds, * or fell into the black hole in the middle. * If all is well, move the Blob in a random direction. */ public void onTick() { // if the blob is outside the canvas, stop if (this.blob.outsideBounds(this.width, this.height)){ this.endOfWorld("Blob is outside the bounds"); } // time ends is the blob falls into the black hole in the middle if (this.blob.nearCenter(this.width, this.height)){ this.endOfTime("Black hole ate the blob"); } // else move the blob randomly at most 5 pixels in any direction else this.blob.randomMove(5); } /** draw this world with a blue background */ public void draw() { this.theCanvas.drawRect(new Posn(0, 0), this.width, this.height, new Blue()); this.blob.draw(this.theCanvas); this.theCanvas.drawDisk(new Posn(100, 150), 10, new Black()); this.theCanvas.drawCircle(new Posn(100, 150), 10, new White()); this.theCanvas.drawRect(new Posn(95, 145), 10, 10, new White()); this.theCanvas.drawLine(new Posn(95, 145), new Posn(105, 155), new Red()); this.theCanvas.drawLine(new Posn(95, 155), new Posn(105, 145), new Red()); } } class BlobExamples{ // examples of data for the Blob class: Blob b1 = new Blob(new Posn(100, 100), 50, new Red()); Blob b1left = new Blob(new Posn(95, 100), 50, new Red()); Blob b1right = new Blob(new Posn(105, 100), 50, new Red()); Blob b1up = new Blob(new Posn(100, 95), 50, new Red()); Blob b1down = new Blob(new Posn(100, 105), 50, new Red()); Blob b1G = new Blob(new Posn(100, 100), 50, new Green()); Blob b1Y = new Blob(new Posn(100, 100), 50, new Yellow()); /** reset the Blob */ void reset(){ b1 = new Blob(new Posn(100, 100), 50, new Red()); } /** test the method moveBlob in the Blob class */ void testMoveBlob(Tester t){ b1.moveBlob("left"); t.checkExpect(b1, b1left, "test moveBolb - left " + "\n"); reset(); b1.moveBlob("right"); t.checkExpect(b1, b1right, "test movelob - right " + "\n"); reset(); b1.moveBlob("up"); t.checkExpect(b1, b1up, "test moveBlob - up " + "\n"); reset(); b1.moveBlob("down"); t.checkExpect(b1, b1down, "test moveBlob - down " + "\n"); reset(); b1.moveBlob("G"); t.checkExpect(b1, b1G, "test moveBlob - G " + "\n"); reset(); b1.moveBlob("Y"); t.checkExpect(b1, b1Y, "test moveBlob - Y " + "\n"); reset(); b1G.moveBlob("R"); t.checkExpect(b1G, b1, "test moveBlob - R " + "\n"); } /** test the method outsideBounds in the Blob class */ void testOutsideBounds(Tester t){ reset(); t.checkExpect(b1.outsideBounds(60, 200), true, "test outsideBounds on the right"); t.checkExpect(b1.outsideBounds(100, 90), true, "test outsideBounds below"); t.checkExpect( new Blob(new Posn(-5, 100), 50, new Red()).outsideBounds(100, 110), true, "test outsideBounds above"); t.checkExpect( new Blob(new Posn(80, -5), 50, new Blue()).outsideBounds(100, 90), true, "test outsideBounds on the left"); t.checkExpect(b1.outsideBounds(200, 400), false, "test outsideBounds - within bounds"); } /** test the method nearCenter in the Blob class */ void testNearCenter(Tester t){ reset(); t.checkExpect(b1.nearCenter(200, 200), true, "test nearCenter - true"); t.checkExpect(b1.nearCenter(200, 100), false, "test nearCenter - false"); } /** the method randomInt in the Blob class */ void testRandomInt(Tester t){ t.checkOneOf(b1.randomInt(3), new Integer[]{-3, -2, -1, 0, 1, 2, 3}, "test randomInt"); } /** the method randomMove in the Blob class */ void testRandomMove(Tester t){ b1.randomMove(1); t.checkOneOf(b1, new Blob[]{new Blob(new Posn( 99, 99), 50, new Red()), new Blob(new Posn( 99, 100), 50, new Red()), new Blob(new Posn( 99, 101), 50, new Red()), new Blob(new Posn(100, 99), 50, new Red()), new Blob(new Posn(100, 100), 50, new Red()), new Blob(new Posn(100, 101), 50, new Red()), new Blob(new Posn(101, 99), 50, new Red()), new Blob(new Posn(101, 100), 50, new Red()), new Blob(new Posn(101, 101), 50, new Red()),}, "test randomMove"); } public void go(){ // construct an instance of a TimerWorld BlobWorld w = new BlobWorld(new Blob(new Posn(100, 200), 20, new Red())); // and run the TimerWorld w.bigBang(200, 300, 0.3); } public static void main(String[] argv){ // construct an instance of a TimerWorld BlobWorld w = new BlobWorld(new Blob(new Posn(100, 200), 20, new Red())); // and run the TimerWorld w.bigBang(200, 300, 0.3); } }