CMPU 101 - Assignment 3 Due: by 11:59 PM on Wednesday, February 15th

$Revision: 1.8 $

This assignment will test your ability to use variables, assignments, expressions, and if/else statements.  It will also introduce you to classes and objects.

Bouncing Ball

You start out this assignment with an almost-complete bouncing ball program.  Here is a screenshot of what the program looks like when finished:

A red ball bounces around a rectangular playing field, changing direction when it hits a wall.  The "Start/Stop" button starts and stops the ball's movement.  The "Reset" button places the ball back in the center of the playing field, randomly assigning it a direction.  The "Quit" button quits the program.

This is a pretty simple program, but it is not too far a leap from this program to games like Pong and Breakout.

Concepts

The program works by representing the playing field as a two-dimensional surface with a fixed width and height.  The ball has a position, specified by x and y coordinates, and a direction/velocity specified by a vector.  The vector's first component, dx specifies the amount by which the ball's horizontal position will change each unit of time, and the second component, dy specifies the amount by which the ball's vertical position will change each unit of time.  Both vector components can be either positive or negative, allowing movement in any direction to be represented.  Here is the screenshot again, but this time with these concepts illustrated.

The origin (0,0) of the playing field is in the upper-left corner.  The lower right of the playing field is found at the point where the x-coordinate is the width of the field and the y-coordinate is the height of the field.

Your Task

Your task is to implement the animateOneFrame method in the PlayingField class.  As its name suggests, this method is invoked once for each frame of animation, and its task is to move the ball and handle collisions with walls (borders of the field).  The program calls animateOneFrame 25 times per second, creating the illusion that the ball is moving.

Classes, Objects, and Methods

Recall that in Lecture 2 we briefly discussed classes and objects.  In this assignment you will start using them!  The animateOneFrame method does its work by making use of an object called ball that represents (what else?) the ball.  It is an instance of the Ball class.  Recall the distinction:

  1. The Ball class represents the characteristics and behaviors of all possible balls, and is a template for Ball objects

  2. A Ball object represents one particular ball.

You will need to make use of the methods that the Ball class defines for Ball objects: by invoking these methods on the object called ball, you can inquire about and change its state.

Step 0: Getting Started

Download cs101-assign3.zip into the Home directory.  Open a terminal window using the toolbar icon that looks like this:

In the terminal, type the command

unzip cs101-assign3.zip

and hit return.  Start DrJava.  Open the files "Bounce.java", "Ball.java", and "PlayingField.java".  These files will be in a subdirectory of Home called "cs101-assign3".

Step 1: Movement

Initially, the animateOneFrame method is empty, so the ball does not move.  As the first step, change the animateOneFrame method so that it contains the following statement:

ball.move();

So, what does this statement mean?  It means:

On the object called ball,
call the method called move without any arguments

The meaning of the move method is simple: it changes the position of the ball (its x and y coordinates) by the amounts indicated by the elements of its direction/velocity vector, dx and dy.  In fact, take a look at where the move method is defined in the Ball class: you can see that is exactly what is happening.

Save and recompile.  Then run the program by typing the command

java Bounce

in the interactions window.  When the "Boing!" window appears, hit the "Start" button.  You will notice that the ball moves.  However, when it reaches the edge of the playing field, it just keeps going.

Step 2: Handling Collisions with the Walls

Rather than allowing the ball move through the walls and off the playing field, you should add code to animateOneFrame so that the ball bounces of the walls at the edge of the playing field.  Specifically, the ball bounces off of a wall if any part of the ball is touching the wall.

When a ball hits a wall, it should bounce off the ball, according to the following rules:

  1. If the ball hits a vertical wall (left or right edge of playing field), the horizontal component of its movement (dx) reverses direction

  2. If the ball hits a horizontal wall (top or bottom edge of playing field), the vertical component of its movement (dy) reverses direction

To detect a collision, you will need to know the ball's current position (x and y coordinates) as well as the ball's radius.  You can get these values using the following statements:

double x = ball.getX();
double y = ball.getY();
double radius = ball.getRadius();

The width and height of the playing field can be determined with the statements

double width = this.getFieldWidth();
double height = this.getFieldHeight();

Using these values, you should be able to determine whether or not a collision has occurred, and if so, to compute new dx and dy values representing the new direction and velocity of the ball object.  You can get the current dx and dy values as follows:

double dx = ball.getDx();
double dy = ball.getDy();

When you have computed new values of dx and dy, you can update the ball object to reflect them using the statements

ball.setDx(updatedDx);
ball.setDy(updatedDy);

where updatedDx and updatedDy are the new values you have computed for dx and dy.

When you have implemented collisions, you should be able to run the Bounce program, click the "Start" button, and see the ball bounce off the walls rather than passing through them.

Extra Credit

For extra credit, you can choose to add any or all of the following features:

Sound effects

In the animateOneFrame method, if you detect a collision, call the playBoingSound method using the statement

this.playBoingSound();

The sound should only be played when there is a collision.  Note that the computers in the Mac lab aren't set up to support sound, so you will need to run the program on a different computer to hear the sound.

Ball color

Find the place in the program where the ball is drawn, and change its color from red to some other color.

Change in velocity

In addition to changing the direction of the ball when a collision occurs, try changing the velocity.  For example, try decreasing the ball's velocity by 5% each time it hits a wall.

Add a comment to the source code near the definition of the animateOneFrame method explaining which extra credit features you implemented.

Saving Your Work

The following information is extremely important:

When you log out of the cs101 account on one of the computers in the Mac lab, all files in the account are deleted.  This policy ensures that all of the software continues to work properly when someone else logs in, and that other students don't accidentally see your homework (and vice versa).  Make sure your save your project in a safe place before you log out!

Here is how you can make a zip file containing your project.  Open a terminal window and enter the following commands:

cd
zip -9r cs101-assign3-solution.zip cs101-assign3

These commands make a zip archive of your project and save it in a file called cs101-assign3-solution.zip.  You can copy this file to a USB drive, a blank CD-R or CD-RW, or email it to your Vassar email account through webmail.  Next time you want to work on the project, just copy the zip file back to the Home directory and unzip it using the commands

cd
unzip cs101-assign3-solution.zip

in a terminal window.

Submitting Your Work

Make an archive of your project, then use the CS 101 Submission Website to upload the archive file.  Make sure the name of the archive file contains "assign3" somewhere in its name.