CS100M Spring 2007
Project 6 Part B
Due Thursday, May 3 at 6 pm


Important! Turn off the file backup feature in DrJava—it causes problems on some system configurations! Go to menu item Edit, then to Preferences, choose the last category Miscellaneous, and uncheck the box that says "Keep Emacs-style Backup Files."

Academic Integrity: You may work on your own or with one partner. You may discuss background issues and general solution strategies with others, but the project you submit must be the work of just you (and your partner). If you work with a partner, you and your partner must register as a group in CMS and submit your work as a pair.


Objectives and background

In this project, you will learn about using arrays and inheritance in Java. Once again, practice incremental development and testing.

You will build upon what you did in Project 5 to make an improved version of BoomShine. Using arrays, you can now get a much more interesting game that involves a larger number of balls. In addition, you will modify the behavior of some of the balls in the game through the use of inheritance.


Files and classes

You will be implementing the functionality of 5 classes for this project: Velocity, ClickBall, HyperBall, TimedBall, and BoomShine. The following classes are provided for you: Vector2D, Point, Walls, Ball, GameFrame, and Colors. You should be familiar with some of these classes from P5.


Getting started

The game is similar to Project 5, but in addition we have different types of balls implemented and we can choose the number of balls in the game. Included in the project files is once again a sample solution (see README.txt for instructions on how to run it).

Let's determine the relationship between the classes. As we saw in P5, classes Velocity and Point both work with Cartesian coordinates x and y but we wrote separate, unrelated classes for them in P5, resulting in redundant code. Now that we have learned inheritance, we create a Vector2D class to represent a general two-dimensional object. Therefore, Vector2D is the parent (base) class of the Velocity and Point classes. ClickBall, HyperBall and TimedBall are all different kinds of balls and therefore are derived from the Ball class. The Colors class provides several static methods for manipulating the color of the balls. Walls is still the bounding rectangle as in P5. The BoomShine class simulates the game according to the rules, and the GameFrame class provides the graphics window functionality.

There are differences between the classes of the same names in P5 and P6. Download the P6 skeleton files and keep them separate from your P5 files. Most importantly, read the provided code thoroughly—do not assume that they are the same as P5 just because a few lines happen to be the same.

As in P5, we recommend that you start with the most independent classes and test your implementation throughout the development process. Below are the details for implementing the individual classes. Be sure to read the second to last section, "Program development," before you start writing code! That section contains suggestions on how you can develop this project incrementally to arrive at a high quality product (submission) in the end. Follow the specifications here and in the comments of the class files. Watch for the comments that start with TODO. These comments describe what to do in each of the methods. Do not change any provided code other than as indicated by the TODO comments in the skeleton files (and possibly the Ball class as described below).


Details of the classes

The Vector2D class (Vector2D.java)

Read this provided class. This class represents 2-dimensional vectors (values with x and y components) and is the base class of Point and Velocity. In P5, you might have noticed that Point and Velocity were extremely similar classes are shared a lot of duplicate code. This is because they do indeed share a common denominator—they are both 2-d vectors quantities. Using inheritance, we can express these shared properties and functionality and avoid duplicating code.

The Point class (Point.java)

This has been provided for you; it has the same functionality of the Point class in P5. Notice that this new Point class is far shorter than that in P5 because here Point extends Vector2D.

The Velocity class (Velocity.java)

You need to implement a new function in this class, getMagnitude. This method would be useful for implementing some of the new behaviors in the Ball subclasses.

The Walls class (Walls.java)

This is provided for you. Note that the method checkBounce is no longer in Walls. That functionality has been moved into the Ball class for reasons that will become clear.

The Ball class (Ball.java)

This is provided for you and is essentially the same class you wrote in P5, but with some changes and additions (make sure you read through the code and understand it). In this class, you can modify the method bodies or add private methods if you like. For example, feel free to replace the given update method with what you wrote for P5 to produce the behavior that you want.

Note that checkBounce, i.e., checking whether the ball is bouncing off the walls, is now a method in Ball. There is a subtle change to checkCollision as well, in that it now sets off explosions on its own when collisions occur.

The color field has been changed to a Java Color object. You now have full control over the colors of Balls. For your convenience, the provided Colors class has static methods that might be helpful in dealing with colors. In particular, the getColor method in class Colors allows you to translate integers into colors, similar to what was done in P5. Class Colors is described near the end of this section.

The ClickBall class (ClickBall.java)

This is a subclass of Ball that should represent a ball with zero velocity and is initialized to explode. Design and implement this class in the skeleton file. (This one should be really short and simple!)

The HyperBall class (HyperBall.java)

This is the first of two more interesting subclasses of Ball that you will write. It should be a Ball that gains or loses some speed when it hits the wall. Design and implement this class in the skeleton file. The requirements are as follows:

As long as you meet the requirements above, you get to be creative in designing the behavior that you want! In our example implementation, a HyperBall speeds up each time after a bounce, up to some maximum speed. Subsequent bounces decrease its speed down to a minimum speed. Then its speed climbs again, and so forth. Our HyperBall's color becomes increasingly bright (white) as it speeds up and increasingly dark as it slows down. Furthermore, it flickers a few times after it bounces off a wall. We encourage you to be creative in making your design, but you can use our design if you like.

You should think carefully about what methods you need to override in order to implement a HyperBall. As a subclass of Ball, HyperBalls already know how to do basic Ball-like things. All you have to do is change—i.e., override—the methods (and only those methods) that are involved in providing the new behaviors needed. As you do this, you may also find that you need to add some fields to HyperBall to support the new functionality. Demonstrate good object-oriented (OO) programming style. For example, use private and public appropriately and use available methods whenever possible. (All of this applies to TimedBall as well.)

The TimedBall class (TimedBall.java)

This is another subclass of Ball; it is one that does not explode right away on contact with an exploding ball. Instead, the explosion is delayed for some amount of time. Design and implement this class in the skeleton file. The requirements are as follows:

As long as you meet the requirements above, you get to be creative in designing the behavior that you want! In our example implementation, a TimedBall has a delayed explosion and it flickers as it travels.

The BoomShine class (BoomShine.java)

Class BoomShine contains the main logic of the game. Unlike in P5, a BoomShine game object will be created. Observe that there are four fields in the class. You need to implement all the methods in the skeleton except main and setFrame. The given main method in BoomShine simply calls a helper method in GameFrame that starts a new instance of the game and manages its execution.

The constructor should initialize the field walls with a reasonably sized Walls object and the field balls with an array of Balls. Your final product (submission) should allow for an array of randomly generated Balls—it must be possible to get a combination of HyperBalls, TimedBalls, and regular Balls in the array in a game. One thing to note: Remember to reserve a place in your array for the ball that represents the user click, since all balls to be drawn must be passed to GameFrame as a single array.

The logic of the game is now in the update method, which performs the equivalent functionality of one iteration of the main loop in P5. Besides updating the status of all the balls in the game, this method should also manage the message displayed in the window indicating how many balls have been exploded. You can decide what it takes to win the game and provide feedback to the user as you like.

The other methods in the class are just simple getters.

The GameFrame class (GameFrame.java)

This provided class is essentially the same as that in P5. In particular, getClick and setMessage work as they did before. There are, however, some key changes that you should be aware of.

The most important change is that GameFrame does not have the addBall method any more. You do not need to explicitly add your Ball objects to the frame. Instead, the getBalls method in BoomShine must return the array of Balls that is to be drawn on the screen at any particular time.

There is no longer a refresh method, and your BoomShine code does not need to call any function to update the game screen. This is taken care of for you.

The Colors class (Colors.java)

This is a class provided to help you work with Java Colors. The getColor method returns a Color object given an integer, so you may use it to make the transition from P5. You should examine the rest of this class for methods that you might find helpful. To do even more with Java Color objects, read its documentation in the Java API.


Program development

You have already learned from P5 that you should start with the most independent classes and test incrementally. What other strategies are useful for dealing with a large project? In this project, the game deals with an array of different kinds of balls. What is an "easier" version of this game? An array with just one kind of balls!

Our suggestion is that you start by completing class Velocity and, if you like, modify class Ball to reflect your game in P5. Then you will be ready to work with class BoomShine to implement a simplified version of the game—a game with just one kind of balls and no user click. Test this simplified version to make sure that it works correctly (check, at least visually, that all the balls are updated correctly). Next implement ClickBall and make sure that it works correctly with the rest of the project. Now you have a fully functional, if simplified, game.

Then you are ready to work with the more complicated subclasses HyperBall and TimedBall, one at a time. Take HyperBall for example, you don't have to implement all the specialized behaviors in one shot! Start by just changing its velocity (or its color or another visual cue). Then modify your code in BoomShine to include HyperBalls in the game and do some testing. If that one behavior that you have implemented is working as you wish, then add another behavior and test again. Repeat the cycle of implementing a single functionality and testing for every functionality that you want to add! This allows for simple debugging and will end up saving you time and giving you a quality product in the end!


Submission and grading

Submit to CMS the .java files for these 6 classes: Velocity, Ball, ClickBall, HyperBall, TimedBall, and BoomShine. Make sure that you submit your *.java files, and not your *.class files. Double check this!

In this final project of the semester, we will reserve two style points for your effort in making the effects interesting. "Interesting effects" can be "flashy" visual effects, or it can be a demonstration of algorithmic or OO thinking. For example, you can simply make the three kinds of balls (not counting the click) three different colors. This satisfies the requirement of being able to distinguish between the different kinds of balls visually, but it is not all that interesting and does not demonstrate any algorithmic or OO thinking. In our example implementation, the flickering travel of a TimedBall may be considered an interesting visual effect. Our HyperBall's change in speed corresponds to a change in color and requires some algorithmic development and OO thinking—fields are used to support the effect (the effect is based on the ball's state). Write code (add fields, override or add methods) to create the effects as necessary! Adding fields unnecessarily, just for the sake of some extra fields, will not get you more style points. Be creative and have fun with the game!