Homework 6 (20 points)
In this assignment, you will practice doing the following :
- writing a program that features animation,
- working with several classes (one class per file),
- using inheritance and abstract classes,
- using the ArrayList class,
- handling keyboard and timer events.
For this homework, you can work in a team of 2 members. Each team should turn in one program. You may also elect to work on your own.
When working at the computer, everyone needs to take a break once in a while. Since computer games are such a popular diversion, here is your chance to write your own computer game. You want to make a game that features a caterpillar eating cabbage heads in a garden. As the caterpillar eats, it grows bigger. To make the game challenging, the garden has also poisonous cabbage heads that can kill the caterpillar. Moreover, as the caterpillar moves around the garden, it dies if it ever crawls over itself.
The game starts with a patch of good and poisonous cabbage heads randomly distributed in a garden. Good and bad cabbages may come in different varieties. The cabbage heads should never overlap. The caterpillar is initially outside the garden. To win, the caterpillar must enter the garden, eat all of the good cabbage heads, and exit the garden. When the caterpillar eats a good cabbage, its body grows in length. The caterpillar dies if it eats a poisonous cabbage head or if it crawls over itself. While a game is going on, the caterpillar should always be in motion. It should not be able to go outside the graphics window or over the garden fence.
Below is a snapshot of an example of the game. The caterpillar (the red line) is crawling in the garden (enclosed by the black fence). The bad cabbages are the red circles. The good cabbages are the white and the multicolored circles. A multicolored circle represents a good cabbage that has also psychedelic effects on the caterpillar. When the caterpillar eats a psychedelic cabbage, it grows and becomes multicolored for a short period of time.
Here is a series of snapshots of the game while it is played.
Some explanations
In this program, you will use at least six classes and one interface (the interface is just used to list the constants). Below is an explanation of some of the features of the classes. Some code is already written in the sample files. Read through it as well. Some key implementations of the program are discussed in our computer lab.
You can change some of the details of the interface of the classes listed below. However, you must use the three classes (Cabbage, Caterpillar, and CaterpillarGame). You can only write methods related to a cabbage in the Cabbage class and its subclasses, and methods related to the caterpillar in the Caterpillar class (obvious but important to make your design clear).
abstract class Cabbage
A Cabbage is the representation and the display of a cabbage head. Since cabbages may come in different varieties, actual cabbage objects are instances of a subclass of Cabbage. It is up to you to create these subclasses. There should be at least three subclasses of Cabbage. An actual Cabbage should be either good (it makes the caterpillar grow) or bad (it kills the caterpillar).
The class features several public methods
- public Cabbage(GWindow window, Point center)
Creates in the graphics window, window, a cabbage centered at Point center.- public abstract void isEatenBy(Caterpillar cp)
A caterpillar is eating this Cabbage: the actual effect on the caterpillar is implemented in a derived class.- public Point getLocation()
Returns the center Point of this Cabbage. Useful to check if a Cabbage created at a location would overlap with this Cabbage (there is no overlap if the two cabbage centers are distant by more than 2 times the radius a cabbage).- public boolean isPointInCabbage(Point p)
Is Point p inside this Cabbage. Useful to check if the head of the caterpillar is inside of this Cabbage.
class Caterpillar
A Caterpillar is the representation and the display of the crawling caterpillar of the game.
The class features several public methods (of course you can add more methods or change any of these):
- The constructor public Caterpillar(GWindow window)
In the graphics window, create a caterpillar initially placed outside of the garden entrance. Store the caterpillar location in an ArrayList of Points. To display the caterpillar, you connect all of the Points of the array (see the sample files and our computer lab). As the caterpillar moves, it can bend at any of these points. To make it easy to manage the motion of the caterpillar, place the points at regular intervals along the body of the caterpillar. Two consecutive points should be distant by the distance the caterpillar moves in one step.- public void move() and public void move(int newDir)
These methods move the caterpillar (they update the ArrayList of points and the display of the caterpillar). move() keeps on moving the caterpillar in the direction it is already moving. move(int newDir) changes the direction of motion of the caterpillar to newDir. The caterpillar must stay within the graphics window. It can't crawl over the fence of the garden. It can't backtrack. If the motion required by any of the move methods is incompatible with these constraints, the method should automatically selects another valid direction of motion.- public void grow()
Whenever the caterpillar eats a good cabbage, it should grow. Add the points at the tail of the caterpillar.- public Point getHead()
Returns the location of the head of the caterpillar. Useful to check if the caterpillar is eating a cabbage.- public boolean isOutsideGarden()
Indicates whether or not all the body of the caterpillar is outside the garden. Useful to find out if the player has won (to win, the caterpillar needs to have eaten all of the good cabbages as well).- public boolean isCrawlingOverItself()
Indicates whether or not the caterpillar' head is going over part of the caterpillar's body. If this is so, the player has lost.class CaterpillarGame
A CaterpillarGame is the representation and the display of the caterpillar game. The display and management of the game is handled by this class.
Here are some of the salient features of this class
A CaterpillarGame has a Caterpillar object and several Cabbage objects. To store the cabbages, use an ArrayList. It has also a GWindow object, window, for the display of the game.
The class extends GWindowEventAdapter to do the animation and handle the keyboard events. The animation is done in the timerExpired method. The speed of the animation is set by the constant ANIMATION_PERIOD, which is the time in milliseconds between 2 timer events.
Whenever a key is pressed on the keyboard (while the window is active), the method keyPressed(GWindowEvent e) is called. Handle in this method any change of direction of the caterpillar.
What you need to do
Starting from the sample files, create a CaterpillarGame that meets the requirements listed above. As already mentioned, you can change some of the interface that I give you. But you must still use three classes, namely Caterpillar, Cabbage and CaterpillarGame and add 3 more classes for the subclasses of Cabbage. As for the implementation, you have to use an ArrayList to keep track of the Cabbages and the Caterpillar. You must also use the constants listed in the interface CaterpillarGameConstants throughout your code. For example, to change the number of cabbages, one should only need to change the corresponding constants in CaterpillarGameConstants.
When done, your program should:
- display the game board, made of a garden surrounded by a fence with an entrance to the garden,
- feature a crawling caterpillar that can move up, right, down and left according to the player's keyboard commands. The caterpillar must always be in motion. It can't crawl outside the window and it can't crawl over the garden fence. If the caterpillar
- feature good and bad cabbages. The bad cabbages kill the caterpillar. The good cabbages make it grow. The cabbage heads should never overlap. There should be at least three kinds of cabbages.
- display messages to the player explaining what is happening (in a JOptionPane message box),
- allow the player to play a new game or terminate the application when a game is over.
Style
This program is meant to give you practice with inheritance. Use inheritance wisely. For example, avoid using the keyword instanceof. Most of the time you can do better by overriding a method in several classes.
Make sure also that you follow usual stylistic guidelines about indentation, whitespace, identifiers, and localizing variables. You should place comments at the beginning of your program, at the start of each method, and on complex sections of code.
Sample code
Cabbage.java, Caterpillar.java, CaterpillarGame.java, CaterpillarGameConstants.java
Your program has to be your own.