CS 105 Lab 9 -- Fall 1998

For your final Java lab (and your final CS 105 lab) you will achieve the ultimate goal of all too many beginning programmers -- making your very own video game. The actual goal, of course, will be to give you some personal experience with the element of Java (and programming in general) that we just finished discussing in class: repetition. Since animation is a natural application of repetition in a program, we will have you build your own version of one of the (if not the) original computer games, "pong".

A working version of the completed applet is included below so that you can understand its functionality (i.e. play with it). You can move the paddle back and forth by moving the mouse within the applet's screen region. The object is hit the little ball with the paddle each time it tries to sneak off the bottom of the playing area. If no ball is in play (i.e. you just started or you missed), you can get a new ball by clicking the mouse in the playing area.


This handout will lead you through the construction of such an applet. However, some of the Java details you will need to complete this task are not included here. Instead, they can be found in the "Java Programming with JavaTools" document. (The following link will take you to this JavaTools documentation .). You should bring the copies of this document (which I distributed for lab 3) with you when you come to lab this week.

If you have questions about the instructions for this lab, you are encouraged to ask them through the discussion area for this lab in the course discussion forum.


Preparation

As usual, you should prepare for this lab by reading completely through this handout and then trying to sketch out the Java code you will type in during lab. The more you think the details through ahead of time, the more likely you will be to get everything completed during lab while we are around to help you if you get into trouble.

Since MetroWerks and CS Bull still do not get along, you will need to do your Java development work using your Netware account or a Macintosh formatted floppy disk. Once you get to lab, go to the "CS 105" folder on Cider Press and copy the "PongStarter" folder to your floppy disk or Netware account

Open the copied folder and double-click on "Pong" (rather than "Pong.java") to start Metrowerks. Once Metrowerks is running, double-click on the name "Pong.java" to prepare adding your code.

Pong.java contains fairly little Java code this time. All we have included are the skeletons of the methods you will be using in your Pong applet.

Variable Declarations

As you may have guessed, Pong has a good bit in common with the bouncing ball applet you have seen in class. Your code will mimic the bouncing ball applet in many ways. At the same time, there are some important differences. You will get into trouble if you ignore these difference. For example:

With all these warnings out of the way, you can get a good start by copying the variables used to keep track of the ball's position and its velocity from the bouncing ball program into your applet. Just as in the bouncing ball applet, you will need variables to keep track of the x and y coordinates of the ball's current position and the rate at which each of these are changing. We might as well stick with the variable names used in the bouncing ball applet for these values: x, y, xspeed, and yspeed.

These variables will be shared by several methods in your applet so their declarations should appear before all method declarations at the start of the applet itself.

The numbers used to describe the ball's speed in the x and y directions are likely to have fractional parts. As a result, you can not use the type "int" that has been appropriate for variables that stood for numbers in all your earlier labs. Instead, use the type "double". Unfortunately, the name "double" doesn't suggest that it corresponds to real numbers in quite the way that "int" suggests integers. This awful name refers to the fact that a variable of type "double" requires twice as much memory. It is a remnant of a day (not so long ago) when computers had very small amounts of memory and programmers had to be careful not to waste what was available.

So, despite the lousy name, declare all four variables as type "double".

Setting the Ball's Initial Position

The animate method will depend on the variables you just declared to decide where to draw the ball at each step and how much to move it between steps. Therefore, before "animate" is invoked by the browser for the first time, you must tell the computer what values to associate with each variable name. The browser always invokes "begin" before any other method in your applet, so this is a good place to make these assignments.

In the "begin" method's body, add assignment statements to make the ball's original y component a small number (like 5), and its initial x component something between 0 and 200 (the width of the applet's default screen area). Also, you will need to assign values to "xspeed" and "yspeed" to specify the rate at which the x and y coordinates should change. Make these values relatively small (in the 2 to 4 range) and make the change per step in the y coordinate a bit bigger than the change in the x coordinate.

Drawing the Ball

The basic steps you will perform in the "animate" method are to:

At this level, "pong" is just like the bouncing ball applet. The difference between the two will be in the details of how the variables that describe the x and y coordinates of the ball are changed.

To get started, add to the body of "animate" a "clearRect" to clear the screen and a "fillOval" to draw the ball at the x and y coordinates determined by the coordinate variables. Once this is done, run your applet. If everything is correct, a small black circle should appear at the top of the applet's screen area.

Moving the Ball

Getting the ball to move isn't too hard either. For the x coordinate of the ball you have one variable, "x", for the current value of the coordinate and another, "xspeed", for how much this coordinate should change during each animation step. To tell the computer to actually change the coordinate, add the assignment

x = x + xspeed;
to the "animate" method before the "fillOval" that draws the ball. This assignment will tell the computer to set the ball's new x coordinate equal to the value of its current x coordinate plus the speed at which you want the ball to move from left to right.

Add a similar assignment for the y coordinate.

Run your applet again. If all is well, the ball should appear near the top of the screen and then move down the screen until it either falls off the bottom or side of the applet's screen area. Since you haven't added instructions to make the ball bounce, that is the last you will see of it. Once it disappears, select "quit" from the "File" menu to stop the animation (it is still drawing the ball somewhere you can't see it).

If it disappeared off the bottom rather than the side, make the initial speed in the x direction larger and run the applet again until you have adjusted the initial speed so that the ball does disappear off the right side of the applet's screen region.

Bouncing

The code required to make the ball bounce is even simpler than it was in the bouncing ball applet since your ball shouldn't slow down when it bounces. To be cautious about this step, we will add the bouncing code one wall at a time. We will treat all four walls the same for now, and then modify the code to account for the fact that the ball should fall off the bottom if the paddle isn't in its way later. If you are feeling confident, don't hesitate to go ahead and do all the walls at once.

The Right Wall

So, since your ball is disappearing off the right side, you should make it bounce their first. To do this, place an if statement after the assignments in "animate" but before the"fillOval" to draw the ball.

The if statement you add should check to see if the x coordinate is greater than 200 (the default width of the applet's screen area). If it is, you simply need to reverse the direction in which the ball moves horizontally. This can be done by replacing the current speed with -1 times the current speed. That is:

xspeed = -1 * xspeed;
Depending on how close to reality you want your animation to be, you could change the x value in this case to reflect the fact that the ball should have bounced instead of briefly passing through the side wall. If you don't bother, only those with good eyes will ever notice.

Once you have added the "if", run the applet. The ball should bounce off the right side and then slide off the bottom. If not, take a close look at your code and/or ask for help.

The Other Walls

At this point, depending on the speeds you picked for your ball initially, it is either falling off the bottom or going through the left wall. What you should do now is add an if statement to make the ball bounce off whatever wall it currently disappears through. Then, run your applet again, see where it disappears next and fix then add an if statement for that wall. In that way, you will add one if statement at a time until you have one for each wall. They will all be similar, but:

When all the if statements are in place, the ball should bounce from wall to wall until you select quit from the file menu.

Adding a Paddle

The paddle is supposed to move whenever you move the mouse. So, you should expect to have to put some instructions in the "mouseMove" method to take care of the paddle when the browser tells you that the mouse has moved. The surprise is that you won't actually draw the paddle in mouseMove. Why? Remember that you placed a "clearRect" in "animate". This is necessary to remove old images of the ball from the screen. Since animate is invoked all the time, however, this "clearRect" would quickly remove any paddle drawn by "mouseMove".

The solution to this is to have "animate" draw the paddle at a location determined by a variable set by "mouseMove". The variable will keep track of the mouse's x coordinate the last time the browser invoked "mouseMove". So:

  1. Add a declaration for a new variable at the top of your applet. "lastX" or "paddleX" might be a good name.

  2. Add an assignment in the "mouseMove" method to set this new variable equal to the "x" parameter the browser passes to "mouseMove".

  3. Add a line to the end of "animate" to draw the paddle. You can do this using a fillRect. Make the paddle about 20 pixels wide. Draw it so that its center is located at the same x coordinate as the last mouse position. Make it 5 pixels high with a "top" y coordinate of 195. This will place it right at the bottom of the applet screen display.

If you run your applet now, you should be able to control the paddle with the mouse. You will notice (possibly with some frustration) that the applet ignores the mouse if you move the mouse pointer out of the applet display area. You will also notice that the ball still bounces off the bottom no matter where the paddle is.

Making the Paddle Useful

To make the paddle important to the game, you have to make it possible for the ball to fall off the bottom again. At this point, your "animate" method should contain an if statement that looks something like:

if ( y > 200) {
      yspeed = -1*yspeed;
}

You don't want to delete this statement. You still need to do something important when the ball reaches the bottom of the screen display. The trick is that what you want to do is itself "conditional". If the paddle is in the right place, you want the ball to bounce. Otherwise, you want to make the ball disappear until the user clicks the mouse to get a fresh ball.

This means that you need to replace the assignment

      yspeed = -1*yspeed'
with another if statement which will depend on the position of the paddle. You will have one if statement (the one about the paddle) contained within another (the one about the ball reaching the bottom of the screen).

The condition of the inner if statement is also a bit complicated. The ball hits the paddle only if it's x coordinate is greater than that of the left edge of the paddle and less then that of the right edge. In Java, conditions involving one condition and another are written by joining the two simple conditions by a double ampersand (&&). So, the if statement you need to write will look like:

if ( first-condition && second-condition ) {
      make the ball bounce
} else {
      make the ball hide
}

You already know how to make the ball bounce. Just negate yspeed as you did before. To make the ball hide, set the y coordinate to something like 250 and the yspeed to 0. This will make the ball wiggle back and forth just below the screen waiting for the player to click.

So, replace the assignment "yspeed = -1 * yspeed" with an if statement for the appropriate conditions that reverses the ball if the condition holds and leaves it in suspended animation otherwise. Then, run your applet and see if the paddle works.

Getting a New Ball

The last step is to provide a way for the player to get another chance by clicking the mouse. For this, you need to add some simple code to "mouseDown". When the ball misses the paddle, you set its yspeed to 0 and its y value to something larger than 200. To get it going again, you should set its y coordinate to 0 and its yspeed back to the initial value you chose in "begin". Just add two assignments that make these changes to the body of "mouseDown" and you should be all set.

Test this change and your applet is complete.

Finishing Up

As usual, when you are done, be sure to incorporate you completed applet into an HTML page and add a link to it from your CS 105 labs page.