Chapter 9 Active Objects + Boxball Project Design • Animations! • What are they? – Snapshots of objects in different positions – When viewed quickly appear to be moving A Virtual Flipbook: Animating an Object • First create an object • Then – Move it a little – Pause for the user to see it – Repeat FallingBall public class FallingBall extends ActiveObject { public FallingBall( Location initialLocation, DrawingCanvas aCanvas ){ canvas = aCanvas; ballGraphic = new FilledOval (initialLocation, SIZE, SIZE, canvas ); start(); } public void run() { while ( ballGraphic.getY() < canvas.getHeight() ) { ballGraphic.move( 0, Y_STEP ); pause( DELAY_TIME ); } ballGraphic.removeFromCanvas(); } } Defining an Active Object • define a class that extends ActiveObject • ensure the class includes a run method • pause occasionally within the run method • include start(); usually as the last statement in the constructor Using Active Objects public class FallingBallController extends WindowController { private FallingBall droppedBall; public void begin() { new Text("Click to make a falling ball…”, INSTR_LOCATION, canvas ); } public void on MouseClick( Location point ) { droppedBall = new FallingBall( point, canvas ); } } What if… • We wanted the falling object to look like a raindrop Image and VisibleImage Classes • In the controller class: private Image rainPicture; rainPicture = getImage("raindrop.gif" ); • Can be used anywhere: new VisibleImage( rainPicture, 0, canvas.getWidth()/2, canvas ); A Controller Class public class FallingRainPicController extends WindowController { private Image rainPicture; public void begin() { new Text("Click to make a falling raindrop…", INSTR_LOCATION, canvas ); rainPicture = getImage( "raindrop.gif" ); } public void onMouseClick( Location point ) { new FallingRainDrop( rainPicture, point, canvas ); } } A Falling Raindrop public class FallingRainDrop extends ActiveObject { private static final int DELAY_TIME = 33; private static final double Y_SPEED=4; private VisibleImage ballGraphic; private DrawingCanvas canvas; public FallingRainDrop( Image rainPic, Location initialLocation, DrawingCanvas aCanvas ) { canvas = aCanvas; rainGraphic = new VisibleImage( rainPic, initialLocation, canvas ); start(); } public void run() { while ( rainGraphic.getY() < canvas.getHeight() ) { rainGraphic.move( 0, Y_SPEED ); pause ( DELAY_TIME ); } rainGraphic.removeFromCanvas(); } } Active Object Interactions • Accomplished with methods and parameters • A RainCloud: – RainCloud continuously generates drops – Drops fall and disappear at the bottom The RainCloud Class public class RainCloud extends ActiveObject { public RainCloud( DrawingCanvas aCanvas, Image aRainPic) { rainPic = aRainPic; canvas = aCanvas; start(); } public void run() { RandomIntGenerator xGenerator = new RandomIntGenerator( 0, canvas.getWidth() ); int dropCount = 0; while ( dropCount < MAX_DROPS ) { new FallingRainDrop( rainPic, new Location( xGenerator.nextValue(), 0 ), canvas); pause( DELAY_TIME ); dropCount++; } } } Interactions Between Active and Non-Active Objects • An Active Object: – Droplet in the shape of an oval • Created at the top of canvas, falls to the bottom • A Non-Active Object: – Waterline in the shape of a FilledRect • Rises as drops fall A New Kind of Raindrop 1. Created at the top of the screen 2. Falls to the bottom 3. Raises the waterline Falling Droplet public class FallingDroplet extends ActiveObject { private FilledOval dropletGraphic; private FilledRect collector; public FallingDroplet( Location initialLocation, DrawingCanvas canvas, FilledRect aCollector ) { dropletGraphic = new FilledOval( initialLocation, SIZE, SIZE, canvas ); collector = aCollector; start(); } public void run() { while ( dropletGraphic.getY() < collector.getY() ) { dropletGraphic.move( 0, Y_STEP ); pause( DELAY_TIME ); } dropletGraphic.removeFromCanvas(); if ( collector.getY() > 0 ) { collector.setHeight( collector.getHeight() + SIZE/4 ); collector.move( 0, -SIZE/4 ); } } } Boxball Classes break problem up • Boxball Class: – sets up arena, title, status message "Let's Play" – sets up bar and easy/med/hard buttons – sets up target box – onMouseClick • if on easy/med/hard button, moves bar to different level • if clickPoint is above bar creates a new Ball Boxball design, continued • Box Class: – manages the FilledRect that is the target – methods to • • • • • Construct a Box moveBox move to different x-position setSize change the size of the box getLeft retrieve the x position of left side of box getRight retrieve the x position of right side Box Class examples • target = new Box(100, 50, canvas); – creates a new Box at x position 100, width 50 • target.setSize(35); – changes width of box to 35 • target.setSize(BALL_SIZE*1.5); – width set to 50% larger than ball • target.moveBox(); – moves box to a random x position Boxball Design, continued • Ball Class – constructor to create a new Ball • remember the canvas in instance variable – run method to animate ball so it drops • while ball is above the bottom of the arena, – advance ball by 10 pixels or so – pause 50 milliseconds or so • after the ball reaches bottom, check if it is within left and right sides of box Ball class constructor examples • Part 3 – new Ball(BALL_SIZE, point, canvas); • ball will be created at point and fall. • Part 4 – new Ball(BALL_SIZE, point, target, canvas); • ball will also be able to access target • to check if within left and right edges • Another possibility— – new Ball(BALL_SIZE, point, arena, target, canvas); • ball will also be able to access arena to tell when to stop – each new variation has to add actual parameters Have fun with challenges • Check with instructor frequently to stay on track • Email code over weekend for help • This is a crucial component to master • Reading textbook can help with concepts