CS51 - Spring 2010 - Lecture 8

  • read the book!

  • Exercise 9.10.1

    public class SlidingBox extends ActiveObject{
       // Constant declarations omitted

       private FilledRect box;
       private DrawingCanvas canvas;

       public SlidingBox( Location boxLocation, DrawingCanvas aCanvas){
          canvas = aCanvas;
          box = new FilledRect(boxLocation, BOXSIZE, BOXSIZE, canvas);
          run();
       }

       public void run(){
          if( box.getX() < canvas.getWidth() ){
             box.move( X_SPEED, 0);
             pause(DELAY_TIME);
          }
          
          box.removeFromCanvas();
       }

  • Active objects
       - class that extends ActiveObject
       - last line in your constructor should be a call to the start() method
       - run() method specifies what the animation should do
          - will often have a while loop in your run method
          - make sure to put in a pause statement

  • review PatheticPong code

  • show PongPaddleBounded demo
       - what changes need to be made to our pathetic pong?
          - our ball moves in all directions (instead of just down)
          - bounces off of the ceiling and walls
          - bounces off of the paddle
       - ball physics
          - how do we get it to move in any direction?
             - rather than just a y-speed, also an x-speed
          - what happens when we bounce, for example, off the right wall?
             - our y speed stays the same, but set out x-speed to negative
          - what about bouncing off the left side? top? bottom?
       - bouncing off the walls
          - check if the ball.getX() < courtLeft
             - positive x movement
          - check if the ball.getX() > courtRight
             - negative x movement
             - make sure to account for the ball width somewhere. In this example, we did it when defining courtRight
       - bouncing off the ceiling
          - similary, check if the ball.getY() < courtTop
             - positive y movement
       - to get the ball to bounce off of the walls, we need to communicate information to the ball class. What information is that?
          - left and right wall, and the ceiling
          - how do we communicate this information?
             - need to pass it through the constructor and save it
             - in this case, we'll pass the FramedRect for the boundary
             - from that, we calculate private instance variables that keep track of the court boundaries
       - bouncing off the paddle
          - there are a few different ways we could do this
          - one way: check two things
             - ball overlaps with part of the paddle
             - the upper half of the ball is above the paddle
          - again, we need information about the position of the paddle? How can we communicate this information?
       - ball movement
          - each time through the loop, move the ball some distance along x and y
          - what is this elapsed time business?
             - System.currentTimeMillis() gives us a notion of time in ms
             - we can get how long we were actually paused for
             - and adjust how far we'll actually move based on how long we were paused for
             - our xSpeed and ySpeed represent how far we need to move every ms
             - the challenge is that the pause method is imprecise. It doesn't pause for exactly the time we want, so the motion can look jerky sometimes. To get smooth motion, we want to take into account how long we actually paused for.

  • show FallingLeaves demo
       - there may be more than one way to do this, but we'll talk about one straightforward approach
       - let's look at the overall behavior
          - when I click, we get multiple leaves to fall (in this case, 10)
          - each time I click I get 10 more leaves
          - the leaves have:
             - different pictures
             - fall at different speeds
             - fall at different locations
             - and don't all fall together at the same time
       - what's going on here?
          - one class (Fall) that extends WindowController
             - draws, sky, sun, grass
             - how do we draw the individual blades of grass?
                - while loop (similar to WhileRailroad demo)
             - onMouseClick method
                - generate a bunch of leaves
          - leaf class (FallingLeaf) that extends ActiveObject
             - should look somewhat similar to FallingBall class (from PatheticPong code)
             - to create a new FallingLeaf, what information do we need to know?
                - first, what characteristics/differences do the leaves have?
                   - different pictures/sizes
                   - fall at different speeds
                   - fall at different x locations
                - information required
                   - canvas (as always)
                   - which image to use
                   - x location
                   - falling speed
                   - screen height (so we know when they're done falling)
                - how do we provide it this information?
                   - constructor!!!
          - look at FallingLeaf class in FallingLeaves code
          - so, now we can create leaves. how are the leaves created?
             - the fall with random images (selected from 2)
             - they fall at random speeds (which someone needs to create)
             - they fall at different x's (which someone needs to create)
             - they don't all fall at the same time
          - we're going to do this with a third class, the Tree class that also extends ActiveObject
             - how could we do this with another class?
                - generate a "random" leaf
                - pause
                - generate another "random" leaf, etc.
             - what information does it need to know?
                - needs to be given some different leaf images
                   - loading images via getImage is slow!
                   - creating new VisibleImages is fast
                   - only call getImage once, and then pass that Image as a parameter to be shown when creating a new VisibleImage
                - needs the screen width
                - needs the screen height
             - what's going to be in the run() method?
                - pick a random leaf pictures
                - pick a random x
                - pick a random speed
                - create the FallingLeaf
                - do this sum fixed number of times
          - look at Tree class in FallingLeaves code
          - look at Fall class in FallingLeaves code

  • show BouncingBasketBall demo
       - dealing with audio clips
          - similar to images, two steps:
             - Define a variable: Audio clip bounce;
             - load the audio clip: bounce = getAudio("hit.au");
             - play the audio clip: bounce.play()
          - as with images, just load (call getAudio(...)) once!
       - two classes:
          - one looks a lot like our other basketball programs however, now, we're using images and we pick up the ball when we move over an image
          - second, is a class that dribbles the ball and extends ActiveObject
             - what does this class do?
                - all it does is dribble the ball
                - How do you dribble a ball?
                   - move it down then up and repeat
             - what information does it need to know to dribble the ball?
                - the VisibleImage of the ball
                - the AudioClip for the bounce sound
             - what other functionality might we need?
                - need to know when to stop dribbling the ball
                - how can we communicate this?
                   - need to create a method
                   - method sets a variable telling the dribbler that we're done bouncing the ball