Ball.java

/* J. Yang 2000
 */
import objectdraw.*;
import java.awt.*;

// Ball used in boxball.  It is created at a location and falls toward
// the bottom of the screen.  When it reaches the bottom, it
// determines if it landed in the box or not and updates a message to
// the user accordingly.
public class Ball extends ActiveObject
{
    // The size of the ball
    private int ballSize;
    
    // The representation of the ball on the screen
    private FilledOval theBall;
    
    // The box the ball is aiming for
    private Box theBox;
    
    // The bottom of the playing area
    private int courtBottom;
    
    // The message giving feedback to the user
    private Text score;
    
    // Construct a new ball and start it falling
    //          ballsize - the size of the ball
    //    point - where the ball should be displayed initially
    //    c - the canvas to draw the ball on
    //    theBox - the box to try to land in
    //    score - the message to display to the user
    public Ball(int ballSize, Location point, DrawingCanvas c, 
                Box theBox, int courtBottom, Text score)
    {
        theBall=new FilledOval(point,ballSize,ballSize,c);
        // Puts it behind the curtain when it reaches the bottom        
        theBall.sendToBack();                
        this.ballSize=ballSize;
        this.theBox=theBox;
        this.score=score;
        this.courtBottom = courtBottom;
        start();
    }
    
    // Return true if this component is inside theBox, false otherwise.
    public boolean insideBox()
    {
        double leftPoint=theBox.getLeft();
        double rightPoint=theBox.getRight();
        boolean leftIn=theBall.getX()>leftPoint;
        boolean rightIn=(theBall.getX()+ballSize ;
        return (leftIn && rightIn);
    }
    
    
    // Drop the ball to the bottom of the playing area.  When it
    // reaches the bottom, check to see if it landed in the box.
    public void run()
    {
        
        final int dropIncrement = 10;
        
        while (theBall.getY() < courtBottom - dropIncrement) {
            theBall.move(0,dropIncrement);
            pause(50);
        }
        if (insideBox()) {
            score.setText("You got it in!");
            theBox.moveBox();
        }
        else {
            score.setText("Try again!");
        }
        theBall.hide();
    }
}

Box.java

//J. Yang 2000

import objectdraw.*;
import java.awt.*;

// A box used within boxball.  It can move horizontally within specific bounds 
// but always stays at the same height.  The width of the box can also be changed.
public class Box
{
    // The representation of the box on the screen
    private FilledRect theBox;
    
    // Used to pick a new horizontal location
    private RandomDoubleGenerator doubleGen;
    
    // The top of the box
    private double top;
    
    // Construct a new box
    // Parameters:
    //          boxSize - the width and height of the box
    //          leftExtreme, rightExtreme - the extreme values for the left edge of the box
    //    theTop - the top row of the box
    //    c - the canvas to draw the box on
    public Box(double boxSize, double leftExtreme, double rightExtreme, double theTop, DrawingCanvas c)
    {
        doubleGen = new RandomDoubleGenerator(leftExtreme, rightExtreme);
        double xValue = doubleGen.nextValue();
        Location topLeftCorner = new Location(xValue, theTop);
        top = theTop;
        theBox = new FilledRect (topLeftCorner, boxSize, boxSize, c);
    }
    
    // Move a box to a random horizontal location within the bounds
    public void moveBox()
    {
        theBox.moveTo (doubleGen.nextValue(),top);
    }
    
    // Change the width of the box.
    public void setSize(double boxSize)
    {
        theBox.setWidth(boxSize);
    }
    
    // Return the x coordinate of the left edge of the box
    public double getLeft()
    {
        return theBox.getX();
    }
    
    // Return the x coordinate of the right edge of the box
    public double getRight()
    {
        double x = theBox.getX();
        x = x + theBox.getWidth();
        return x;
    }
}

Boxball.java

//J. Yang   B. Lerner  2000

// Updated J. Teresco, Feb 2002

//Simple game of trying to put a ball into a box

import objectdraw.*;

import java.awt.*;

import java.awt.event.*;



/* Boxball is a game in which the user drops a ball from a height 

   trying to get the ball to land in a box.  There are three difficulty 

   levels.  Increasing difficulty makes the box smaller and increases the

   height from which the ball must be dropped. */

public class Boxball extends WindowController implements AdjustmentListener

{

    //dimensions of boxBall court

    private static final int COURT_LEFT = 50, COURT_TOP = 50,

        COURT_HEIGHT = 400, COURT_WIDTH = 400,

        COURT_BOTTOM = COURT_TOP + COURT_HEIGHT,

        COURT_RIGHT = COURT_LEFT + COURT_WIDTH;

    

    private FramedRect court;

    

    //place to write scores,etc

    private Text scoreText;

    

    // Location of score text

    private static final int SCORE_BOTTOM = COURT_BOTTOM + 30,

        SCORE_LEFT = COURT_LEFT + (COURT_WIDTH / 2) - 50;

    

    // The box to drop the ball into

    private Box targetBox;

    

    //buttons for levels of play

    private Scrollbar level;

    

    

    // The line above which the ball must be dropped.

    private Line startingLine;

    

    private static final int LEVEL_SPACING = COURT_HEIGHT / 4,

        HARD_HEIGHT = COURT_TOP + LEVEL_SPACING,

        MEDIUM_HEIGHT = HARD_HEIGHT + LEVEL_SPACING,

        EASY_HEIGHT = MEDIUM_HEIGHT + LEVEL_SPACING;

    

    // Size of the ball

    private static final int BALL_SIZE = 20;

    

    // Box sizes depending on level

    private static final double EASY_BOX_SIZE = 2 * BALL_SIZE,

        BOX_SHRINKAGE = .75 * BALL_SIZE;;

    

    // Height at which the ball must currently be dropped.

    // Determined by the level.

    private int clickHeight;

    

    

    // Create the playing area.  Initialize the game at the easy level.

    public void begin()

    {

        // Create the parts of the game that do not change

        court=new FramedRect(COURT_LEFT, COURT_TOP, COURT_WIDTH,

                             COURT_HEIGHT, canvas);

        

        // A white rectangle below the court to allow the ball to

        // disappear gracefully.

        FilledRect curtain = new FilledRect (COURT_LEFT, COURT_BOTTOM + 1, 

                                             COURT_WIDTH, BALL_SIZE, canvas);

        curtain.setColor (Color.white);

        

        scoreText=new Text("Let's play!",SCORE_LEFT,SCORE_BOTTOM,canvas);

        scoreText.setFontSize(14);

        scoreText.setBold();

        

        // create and display the game-level scrollbar

        level = new Scrollbar(Scrollbar.VERTICAL, EASY_HEIGHT, 1,

                              HARD_HEIGHT, EASY_HEIGHT);        

        add (level, BorderLayout.EAST);

                

        // ask to be notified when scrollbar is used

        level.addAdjustmentListener(this);

            

        // Initialize the game to easy mode

        targetBox = new Box(EASY_BOX_SIZE, COURT_LEFT, 

                            COURT_RIGHT - EASY_BOX_SIZE, 

                            COURT_BOTTOM - EASY_BOX_SIZE, canvas);

                

        clickHeight = EASY_HEIGHT;

        startingLine = new Line(COURT_LEFT, EASY_HEIGHT, 

                                COURT_RIGHT, EASY_HEIGHT, canvas);

        startingLine.setColor(Color.gray);

    }

    

    

    // Handle mouse clicks.  If the user clicks in the court above the

    // starting line, a new ball is created and dropped.  If the user

    // clicks in a button, the difficulty level changes.  Other clicks

    // are ignored.



    public void onMouseClick(Location point)

    {

        //checks to see if the click is inside the court

        if (court.contains (point)) {

            // Make sure the user clicked above the starting line

            if (point.getY() < clickHeight) {

                Ball b = new Ball(BALL_SIZE, point, canvas, 

                                  targetBox, COURT_BOTTOM, scoreText);

            }

        }

    }

        

    // When the scollbar is used, this method is invoked by the AWT to

    // adjust the level of the line that determines how high the ball

    // must be when dropped and the width of the box

    public void adjustmentValueChanged(AdjustmentEvent e) {

        

        startingLine.setEndPoints(COURT_LEFT, level.getValue(),

                                  COURT_RIGHT, level.getValue() );

        

        targetBox.setSize(EASY_BOX_SIZE - 

                          BOX_SHRINKAGE*( EASY_HEIGHT - level.getValue()) 

                          / (EASY_HEIGHT - HARD_HEIGHT));

    }

}