// CS U213 Spring 2009 // moon-walker.java // A simple example of the World game import draw.*; import geometry.*; import colors.*; /* +---------------+ | MoonWalk | +---------------+ | Crater crater | | Walker walker | +---------------+ */ // to represent a Moon walker world class MoonWalk extends World{ Crater crater; Walker walker; MoonWalk(Crater crater, Walker walker) { this.crater = crater; this.walker = walker; } // respond to key event by changing the direction of the walker World onKeyEvent(String ke){ return new MoonWalk(this.crater, this.walker.onKeyEvent(ke)); } // on tick move the walker in the current direction // and update time for the crater World onTick(){ if (this.crater.eatsWalker(this.walker)){ return endOfWorld("Walker fell into the crater"); } else { return new MoonWalk(this.crater.onTick(), this.walker.onTick()); } } // draw this world boolean draw(){ return this.crater.drawCrater(this.theCanvas) && this.walker.drawWalker(this.theCanvas); } // start the world and the timer boolean go() { return this.bigBang(200, 200, 0.1); } } /* +----------+ | Crater | +----------+ | Posn loc | | int time | +----------+ */ // to represent a Moon crater class Crater { Posn loc; int time; Crater(Posn loc, int time) { this.loc = loc; this.time = time; } // the crater disappears once the time runs out Crater onTick(){ if (this.time > 0){ return new Crater(this.loc, this.time - 1); } else{ return this; } } // did this grater eat the given walker? boolean eatsWalker(Walker w){ return Math.abs(this.loc.x - w.pos.x) + Math.abs(this.loc.y - w.pos.y) < 10; } // draw this crater on the given Canvas boolean drawCrater(Canvas c){ if (time > 0){ return c.drawDisk(loc, 10, new Black()); } else{ return c.drawDisk(loc, 1, new Black()); } } } /* +----------+ | Walker | +----------+ | Posn pos | | int dir | +----------+ */ // to represent a Moon walker class Walker { Posn pos; int leftRight; int upDown; int UP = -3; int DOWN = 3; int LEFT = -3; int RIGHT = 3; int STOP = 0; Walker(Posn pos, int leftRight, int upDown) { this.pos = pos; this.leftRight = leftRight; this.upDown = upDown; } // produce a walker heading in the direction given by the key Walker onKeyEvent(String ke){ if (ke.equals("up")){ return new Walker(this.pos, this.STOP, this.UP); } else {if (ke.equals("down")){ return new Walker(this.pos, this.STOP, this.DOWN); } else {if (ke.equals("left")){ return new Walker(this.pos, this.LEFT, this.STOP); } else {if (ke.equals("right")){ return new Walker(this.pos, this.RIGHT, this.STOP); } else{ return this; }}}} } // produce a walker that moved one step on tick Walker onTick(){ return new Walker(new Posn(this.pos.x + this.leftRight, this.pos.y + this.upDown), this.leftRight, this.upDown); } // draw this walker on the given canvas boolean drawWalker(Canvas c){ return c.drawDisk(this.pos, 5, new Red()); } } class Examples{ Examples(){} int UP = -3; int DOWN = 3; int LEFT = -3; int RIGHT = 3; int STOP = 0; Crater cr1 = new Crater(new Posn(20, 30), 15); Crater crGone = new Crater(new Posn(80, 30), 0); Walker neal = new Walker(new Posn(100, 100), this.STOP, this.UP); Walker nealMoved = new Walker(new Posn(100, 97), this.STOP, this.UP); Walker nealDown = new Walker(new Posn(100, 100), this.STOP, this.DOWN); Walker nealLeft = new Walker(new Posn(100, 100), this.LEFT, this.STOP); Walker nealLeftMoved = new Walker(new Posn(97, 100), this.LEFT, this.STOP); Walker nealRight = new Walker(new Posn(100, 100), this.RIGHT, this.STOP); Walker nemo = new Walker(new Posn(22, 28), this.DOWN, this.STOP); Canvas c = new Canvas(400, 400); // test the method onTick in the class Crater boolean testOnTick(){ return (check this.cr1.onTick() expect new Crater(new Posn(20, 30), 14)) && (check this.crGone.onTick() expect this.crGone); } // test the method eatsWalker in the class Crater boolean testEatsWalker(){ return (check cr1.eatsWalker(neal) expect false) && (check cr1.eatsWalker(nemo) expect true); } // visual test for drawing a crater boolean drawCrater(){ return cr1.drawCrater(this.c) && crGone.drawCrater(this.c); } // test the method onKeyEvent in the class Walker boolean testOnKeyEvent(){ return (check this.nealLeft.onKeyEvent("up") expect this.neal) && (check this.neal.onKeyEvent("up") expect this.neal) && (check this.nealLeft.onKeyEvent("down") expect this.nealDown) && (check this.nealLeft.onKeyEvent("right") expect this.nealRight) && (check this.nealLeft.onKeyEvent("x") expect this.nealLeft) && (check this.nealDown.onKeyEvent("left") expect this.nealLeft); } // test the method onTick in the class Walker boolean testOnTickWalker(){ return (check this.neal.onTick() expect this.nealMoved) && (check this.nealLeft.onTick() expect this.nealLeftMoved); } // a visual test for drawing a walker boolean drawWalker(){ return this.neal.drawWalker(this.c) && this.nemo.drawWalker(this.c); } boolean drawAll(){ return this.c.show() && this.drawCrater() && this.drawWalker(); } MoonWalk mw = new MoonWalk(this.cr1, this.neal); /* To run the program type in the Interactions: Examples e = new Examples(); e.mw.bigBang(400, 400, 0.1); */ }