416-11.3

COMP 416, Fall 2006

Program assignment: The Stanley Cup of Java

This is a hard program, so start early. You can work alone or in pairs, but if you work with a partner, be sure you understand the entire program.

Due: Program design, October 3, 4:30pm

List the classes you plan to implement, and for each, the properties and methods they will contain. It is completely all right if you have to change your design as you do the implementation, but at least you will have a point from which to depart. The design will end up being most of your program documentation.

Due: Final program, October 12, 4:30pm

There is no class this day, but the front office will be open for submitting your program. Put your html and all you .class files (but not your .java files) in your University web folder, but don't link the html to anything. Turn in a printout of your html (on which you identify the html file name and sign a pledge) and of all your .java files. Two sided printing is ok. Please staple your pages (don't fold the corners over).

What's required

Write an applet class with appropriate other classes to implement a simple hockey program like the one demonstrated in class. The applet will have three required panels. See Figure 2.

Top panel:

Appropriately labeled text field to enter the desired number of pucks.

If you implement the Zambonis®[1], then a second appropriately labeled

text field for the number of Zambonis.

Middle panel: (graphics panel)

Hockey rink: a square with inside dimensions 300 by 300 pixels.

Goal: a three-sided figure with inside dimensions 40 pixels wide by

20 pixels high.

Paddle (what passes for the blade of a hockey stick): a skinny rectangle

60 pixels wide by 4 pixels high.

Text showing the number of goals scored.

Use constants for all the dimensions so that they are easy to change.

Bottom panel:

Start and stop buttons.

Operation

The applet should appear with some minimal stuff around it (see Options). The user fills in the desired number of pucks and (optionally) the number of Zambonis and presses the start button. The game begins and proceeds until the stop button is pressed. A new game starts over when the start button is pressed again.

Errors checked for

None required (see Options)

Restrictions

The program need not handle non-integer input in the text fields (e.g. anything that causes Integer.parseInt() to throw an exception). You need not handle invalid integer values (e.g. -5) either, although it is easy to do.

Moving and Bouncing

To make things a little more interesting, we'll use our own version of physics to determine how pucks move and bounce off things. First, we will assume that the ice is really slippery so that friction is zero. A puck keeps moving until it enters the goal.

Each puck will have an x and y position (px, py), and a velocity indicated by delta x and delta y (dx and dy). If the puck is at point (px, py) at time t, then at time t+1 (assuming it doesn't hit anything) its new position will be (px+dx, py+dy). The values of dx and dy are restricted to: -3, -2, -1, 1, 2, and 3[2]. When a puck hits a horizontal surface, its velocity in the x direction doesn't change; its velocity in the y direction changes sign (to indicate the change in direction) and has its magnitude set randomly to 1, 2, or 3. See handout 416-10 for a class that handles the sign change and the random magnitude change.

Bouncing off a wall is easy to determine. If the puck is at (px, py) and if moving it to its next position (px+dx, py+dy) takes it beyond one of the walls (e.g. x value less than the left wall or greater than the right wall; y value less than the top wall or greater than the bottom wall), then the puck must bounce. Bouncing off a box is a little harder, but not by much. You know the box's left and right x boundaries and its top and bottom y boundaries. So it is easy to determine if the proposed new puck position (px+dx, py+dy) is inside or outside of that box. If (px+dx, py+dy) is inside the box, we must bounce, but which way? It turns out that since the walls of the box are horizontal and vertical, then at most one of (px+dx, py) and (px, py+dy) will be inside the box. If it's (px+dx, py), then we have a hit on a vertical surface. If it's (px, py+dy), then we have a hit on a horizontal surface. (Think about this). It is possible that (px+dx, py+dy) will be inside the box, but neither (px+dx, py) nor (px, py+dy) is in the box. This happens when the puck is approaching the corner of the box. In this case, you can choose arbitrarily either a horizontal or vertical hit. This isn't exactly right, but it is unlikely that you will notice the anomaly.

The puck should bounce off the walls of the rink, off the front, back, and sides of the paddle, and off the outside (side, front of the sides, and back) of the goal. See Figure 1 below. The pucks do not interact with each other (that's a much harder problem) and do not interact with the Zambonis (if you have Zambonis).

If the puck enters the goal, it should stop moving and the goal counter should increase.

Pucks can start anywhere on the rink. One easy thing to do is start all the pucks in the upper left corner with a velocity of (1,1) which will start them moving down and to the right. This will superimpose all the pucks on top of one another until the first bounce.

The paddle should move left or right with the arrow keys (KeyEvent.VK_LEFT and KeyEvent.VK_RIGHT or 37 and 39). Make sure your paddle stays inside the rink.

Options

Make sure you have the basic version running before you attempt the options. Options will get you a little extra credit, but do not compensate for a poor quality program.

1. Surrounding html. Add some interesting things around the applet window (e.g. Carolina Hurricanes logo, etc.), but don't get carried away.

2. Zambonis. Have Zanbonies go around the ice appropriately. They should not interact with the pucks. It's also ok it they pass right through the goal and paddle. It’s a harder problem to make them avoid the goal and paddle. If you do have Zambonis, consider making both the Puck class and the Zamboni class implement a common interface. That way, you can have an array (or better yet, an ArrayList or Vector) of IceThings and move everything by just going through the array calling a move method on each.

3. Error checking. Handle the case where the user's input is invalid. Input is invalid if it is not a single valid integer greater than 0. Catching invalid values (e.g. -5) is easy. Catching invalid format is best done using a try/catch block and catching the NumberFormatException.

4. Anything else you want to add to increase the excitement of the game.

Figure 2. The applet window.

[1] ZAMBONI and the configuration of the ZAMBONI ice resurfacing machine are registered by the U.S. Patent and Trademark Office as the trademarks of Frank J. Zamboni & Co., Inc

[2] Notice that dx and dy cannot be zero. This avoids some problems like having the puck stop.