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 

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, March 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 ActionListener
{
    //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;
    
    
    // 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,
        MEDIUM_BOX_SIZE = BALL_SIZE + BALL_SIZE / 2,
        HARD_BOX_SIZE = BALL_SIZE + BALL_SIZE / 4;
    
    // Height at which the ball must currently be dropped.
    // Determined by the level.
    private int clickHeight;
    
    // Checkboxes for level selection
    private Checkbox easy, medium, hard;

    // Location and dimensions of the easy, medium, hard buttons
    private static final int BUTTON_HEIGHT = 50,
        BUTTON_WIDTH = COURT_WIDTH / 5,
        BUTTON_TOP = SCORE_BOTTOM + 20, 
        BUTTON_SPACING = COURT_WIDTH / 10,
        EASY_BUTTON_LEFT = COURT_LEFT + BUTTON_SPACING,
        MEDIUM_BUTTON_LEFT = EASY_BUTTON_LEFT + BUTTON_WIDTH + BUTTON_SPACING,
        HARD_BUTTON_LEFT = MEDIUM_BUTTON_LEFT + BUTTON_WIDTH + BUTTON_SPACING;
    
    // Location of the button labels
    private static final int BUTTON_LABEL_BOTTOM = BUTTON_TOP + 
        BUTTON_HEIGHT / 2,
        BUTTON_TEXT_OFFSET = BUTTON_WIDTH / 3;

    // 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();
        
        // creates the game-level radio box and button
        Panel radioButtonPanel = new Panel();
        CheckboxGroup checks = new CheckboxGroup();
        easy=new Checkbox("Easy", true, checks);
        medium=new Checkbox("Medium", false, checks);
        hard=new Checkbox("Hard", false, checks);
        radioButtonPanel.add(easy);
        radioButtonPanel.add(medium);
        radioButtonPanel.add(hard);
        Button button = new Button("Set Level Now");
        radioButtonPanel.add(button);
        add (radioButtonPanel, BorderLayout.SOUTH);

        // request notification if the button is clicked
        button.addActionListener (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);
            }
        }
    }
        
    // Handle button presses
    public void actionPerformed (ActionEvent event) {

        // this means someone pressed the level selection button, so we
        // see which checkbox is currently checked and set the level
        if (easy.getState()) {
            targetBox.setSize (EASY_BOX_SIZE);
            clickHeight = EASY_HEIGHT;
            startingLine.moveTo (COURT_LEFT, clickHeight);
        }
        else if (medium.getState()) {
            targetBox.setSize (MEDIUM_BOX_SIZE);
            clickHeight = MEDIUM_HEIGHT;
            startingLine.moveTo (COURT_LEFT, clickHeight);
        }
        else if (hard.getState()) {
            targetBox.setSize (HARD_BOX_SIZE);
            clickHeight =  HARD_HEIGHT;
            startingLine.moveTo (COURT_LEFT, clickHeight);
        }
    }
}