Assignment 5: Inheritance, Abstract Classes, final
Objective: Create a small game and practice writing child classes.
Due: Before Wednesday's Class
Recommendation: Complete at least through part of part 3-4 before Monday, for timely completion of the assignment and to identify any issues/questions/comments you may have.
Set Up
Copy the
directory /csdept/local/courses/cs209/handouts/assign5
and its contents into your cs209
directory.
Part 1: Compiling and Running the Code
- Compile the code using
javac *.java
orjavac Game.java
. - Run the game by executing
java Game
You should see a black pop-up window with a little dude--the professor--in the bottom right corner of the screen, walking. - Using the arrow keys, move the professor around the screen. Use the space bar to stop him.
- To stop the program, close the window.
Part 2: Understanding the Code
To help you with understanding the code, here are the Java docs for the game code. Refer back to them while completing the assignment, as it may help you to figure out what is inherited and who can do what.
- Start by looking at
Game.java
. There is a lot of code that you don't need to worry about. Focus on themain
andanimate
methods as well as the instance variables.The
main
method creates a new Game object, including setting up the window.main
also calls theanimate
method, which starts the game running.The
animate
method creates the professor and moves the professor. The professor's direction is determined by pressing keys. - Then, look at
GamePiece.java
. (This class contains some less-than-ideal coding practices; bear with me--we haven't seen the techniques to fix them yet.)Note the instance variables, the constructor, and the available methods--especially the
move(Game game)
method. - Now, look at
Human.java
. Look at the class's constructor and themove
method. Hopefully, you're now seeing how the pieces fit together.
Part 3: Creating Child Classes (60 pts)
There should be a lot more thinking than there is coding for this part. The amount of code you need to write is not huge. Think about the behavior of each class and how that should be implemented.
- Create a
Goblin
class, which inherits fromGamePiece
. There are several animated gifs to choose from. A Goblin should "chase" the professor instead of just standing there, which is what the inheritedGamePiece
'smove
method does. Since you are overriding the move method, the method should have exact same signature (i.e., the same parameters) as the parent's move method. How can you make the compiler help enforce that the child class's method has the same signature as the parent?The
Goblin
'smove
method should look completely different from theHuman
'smove
method. - Create a
Treasure
class, whose image is the gem. The gem will move around the window, periodically and randomly. Note that theTreasure
should not change positions during every iteration of theanimate
loop. (You may choose to enforce this restriction either in theTreasure
'smove
method orGame
'sanimate
method, but themove
method is the more appropriate place for easier design.) Also, the top 20 pixels of the window (indicated byYMIN_DISPLAY
) are covered by the menu bar.
Part 4: Updating the Game Class (20 pts)
- Edit
Game
'sanimate
method. Create a Goblin object and a Treasure object. Start the Goblin in the upper left corner. The Treasure should be at a random spot in the window. - Call the Treasure and Goblin's
move
method to make them move. - Call the Treasure and Goblin's
draw
method to display them. The window "refreshes" each frame, so you'll need to draw each object, even if you don't move it.
Part 5: Using Abstract Classes in the Game application (35)
Cannot be completed until after Monday's class.
Refactoring
This assignment is an example of a typical design/implementation process. Start with your original code design: inheritance from GamePiece class. You realize it could be designed better, so you change the design/implementation. With the revision, it is now easier to add new functionality to Game.
Now for the refactoring of your code:
- First, clean up your code. If you did not use
the
@Override
annotation on themove
methods of your child classes, you should add that. If you get errors, fix the errors (most likely caused by not using the appropriate parameters). - Modify the
GamePiece
class so that it is anabstract
class with anabstract
move
method. - Modify the
Game
class'sanimate
method to have an array ofGamePiece
objects, which contains theGamePiece
objects that you just created. Iterate through the objects, calling themove
anddraw
method on each object. (If you're getting errors, you likely didn't override themove
method correctly.) Is there any other way you can make the code more concise? - Make all appropriate methods in the
GamePiece
class befinal
methods. - Test your new code.
The coding part of this assignment should be straightforward. The explanations in your comments are more important.
- In comments in
GamePiece
,- discuss why making
GamePiece
abstract is a better approach to the code's design - justify your choices of methods becoming
final
in comments.
- discuss why making
- In comments in
Game
,- explain why we can call the
move
method on aGamePiece
object--a method that is abstract--and the application does the "right" thing - discuss all the steps you would need to take to add a new Goblin that has a different movement behavior (e.g., zig-zags across the screen) to the game. Don't talk about the zig-zag behavior in particular--I just want to give you a concrete idea of a different behavior. It should be clear from your description that you know all the steps required to implement this new behavior in the game.
- explain why we can call the
Extra Credit (up to 15 points)
Complete all of the above requirements before doing extra credit.
Add the overlap
method to
the GamePiece
class. The signature
for overlap
will look something like
public boolean overlaps( GamePiece gp )
. It will
return true iff the GamePiece overlaps the GamePiece passed to
the overlap
method as a parameter. Note that, if you
haven't done so already, you'll need to adjust the value of the
img_width
or char_width
variables
of the respective child classes, depending on the size of animated
gif you chose. Try a value of 15 to start.
There is a lot more that can be done on this assignment--actually make the game stop, winning or losing, adding goblins (with different types of fmovements), ... Be creative, but keep the code neat.
Turning in Your Assignment
Copy your assign5
directory into your
turnin directory, using the turnin.sh
script.
Grading (115 pts)
You will be evaluated based on the following criteria:
- (80 pts) correctness and OO style of your classes, including use of abstract, final
- (15) adding abstraction
- (20 pts) discussion comments