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.
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.
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.
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).
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.
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
.
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.
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.
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 Ball
s. 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.
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!)
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:
HyperBall
from other kinds of Ball
s.HyperBall
.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
,
HyperBall
s 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.)
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:
TimedBall
does not explode immediately upon contact
with an exploding ball. The amount of delay should be reasonable for the game.TimedBall
from other kinds of Ball
s.TimedBall
.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.
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 Ball
s. Your final product (submission) should
allow for an array of randomly generated Ball
s—it must be
possible to get a combination of HyperBall
s, TimedBall
s,
and regular Ball
s 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.
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 Ball
s
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.
Colors
class (Colors.java)This is a class provided to help you work with Java Color
s.
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.
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 HyperBall
s 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!
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!