The goal for this project is to develop a version of the classic video game Asteroids. If you've never played Asteroids, we encourage you to find an on-line version to try.
All of the graphics for this application will be handled by the StdDraw library developed by Robert Sedgewick and Kevin Wayne at Princeton University. This library is not particularly powerful or full-featured but it makes it easy to develop simple graphical applications in Java.
The following driver initializes the drawing window and handles the main game loop:
GameDriver.java (DO NOT MODIFY)
It is your responsibility to develop an AsteroidsGame
class that implements the following interface:
The Playable
interface includes an "update" method
that should update the state of all game elements at each time step,
and a "draw" method that should re-draw game elements after they have
been updated. Your code will be tested using the driver above.
It will be necessary to store and update the locations (using rectangular coordinates), orientations (using an angular measure), and velocities (using a vector representation) of game elements. The following classes encapsulate this kind of information.
Point
class is an encapsulation of a two-dimensional
location that uses rectangular screen coordinates. Pose
class is a
subclass of Point that includes heading/orientation information (an
angular measure). Vector2D
class represents a two-dimensional
vector. Vectors of this sort may be visualized as arrows with both a
direction (or heading) and a length (or magnitude). Vectors may be
used in this application to represent both the velocities and
accelerations of game elements.
GameUtils.java contains utility
methods for working with the classes above. In particular, it includes
a method for drawing a triangle for a particular Pose
(which will be useful when drawing the Ship
).
Note that Point
, Pose
,
and Vector2D
are immutable classes. The use of
immutable classes can help to avoid subtle bugs that result from
accidentally aliasing mutable objects.
The GameDriver
class is organized so that it
will support any game that implements
the Playable
interface. The following two classes
provide an example of a very simple "game" that
implements Playable
and makes use of some of the
helper classes provided above.
You can try out BounceGame by changing line 40
of GameDriver.java
as follows:
// game = new AsteroidsGame(); game = new BounceGame();
To be clear: neither of these classes will be used in your Asteroids implementation. They are only provided as an example.
You must provide implementations for the following game elements.
The Asteroids must fulfill the following requirements:
StdDraw
pen radius of .002.
Enemy saucers must fulfill the following requirements:
GameUtils.drawPoseAsTriangle
method do draw the ship to
the screen.
StdDraw.isKeyPressed
to detect keyboard events.
java.awt.event.KeyEvent.VK_LEFT
) the
ship must be turned .1 radians to the left. If the user is
pressing the right arrow
key java.awt.event.KeyEvent.VK_RIGHT
the ship must be
turned .1 radians to the right. Note that you don't need to worry
about keeping heading values within the range 0 to 2π. All of
the provided heading-related methods will perform correctly for
values outside of this range.
java.awt.event.KeyEvent.VK_DOWN
, a
thrust of .1 pixels/time step squared must be applied. The thrust
must push the ship in the direction represented by its current
heading. applyThrust
method defined in the
GameUtils
class may be used to update the ship's
velocity vector.StdDraw.hasNextKeyTyped
and
StdDraw.nextKeyTyped
methods to detect space bar
presses.
When the game starts, the ship must be present on the game screen along with 100 stars, the two numeric displays and 10 asteroids. It is not necessary to guarantee that the the ship is safe from asteroids when the game starts. If the ship appears inside an asteroid, that's just bad luck for the player.
The size of each asteroid must be determined randomly when it is created. Each asteroid must have a 50% chance of being large and a 25% chance of being small or medium.
There must be no saucers on the initial game screen. A new saucer must be added to the game screen on each time step with a probability of .002. Note that this means there may occasionally be more than one saucer present on the game screen. Again, it is possible for saucers to appear in a location that will cause an immediate collision with the ship.
For the purposes of collision checking, the game elements can be divided into three categories.
It is not necessary to perform pixel-level collision detection. Instead, you should perform approximate collision detection by associating each game element with an appropriate collision radius. For the case of the circular elements (Asteroids and Bullets) this should match the radius of the element. For the case of non-circular objects (Ship and Saucers) this radius should be chosen to be half the length of the longest axis of the element. For example, the ship's longest axis is 20 pixels, so the collision radius should be 10 pixels. A collision should occur whenever two objects are near enough that the circles defined by their collision radii overlap.
Whenever a collision occurs, both elements involved in the collision must be destroyed and removed from the screen. The player's score must be increased by the point value associated with the Asteroid or Saucer that was involved in the collision.
If the player's ship is destroyed, and the player has remaining lives, then a new ship should be created at the starting location.
If the player loses all three lives, then no future game updates must occur: the game screen must freeze. The Lives Remaining indicator must read 0 and the score should reflect the final collision that caused the game to end.
Any time the player manages to destroy all of the Asteroids and Saucers on the game screen, a new "level" should begin: the correct number of new asteroids must appear at randomly selected locations. The position of the ship and the position of the stars should not be modified.
The following video illustrates how the completed game should look:
The readiness quiz for this assignment will include questions on UML. YOU MUST ANSWER ALL QUESTIONS CORRECTLY TO GET ANY CREDIT FOR THIS PART. You may take the quiz as many times as necessary.
By the deadline for this part you must submit a UML diagram illustrating your design. For full credit, your design must make appropriate use of the object oriented features that we have been covering in class: specialization, abstract classes, interfaces, etc. Your UML should be as complete as possible. It should show the attributes of each class as well as the signatures of all public and protected methods. It should also show the relationships between your classes.
Part of your grade for this portion of the assignment will be based on using correct UML "syntax". Your UML diagram may be prepared electronically or very neatly hand-drawn and scanned. This page lists some tools for preparing UML diagrams.
You are free to brain-storm design ideas with other students in the class. The final UML diagram must be prepared and submitted individually, but you are encouraged to discuss the design with others. If you do work with another student in developing your design, you must acknowledge that assistance in your submission.
Your UML design document must include a few paragraphs describing and defending your design decisions. For full credit this document must include precise definitions of inheritance and polymorphism, along with citations for the source(s) for your definitions. The formal definitions must be supplemented by short explanations of the terms in your own words. The design document must explicitly point out where inheritance and polymorphism are used to prevent code duplication. It may also be appropriate to use the concepts of coupling and cohesion to justify aspects of your design.
Your UML diagram must be submitted through Canvas as a .pdf file.
No late submissions will be accepted for Part B.
Design supports the required functionality | 15% |
Correct UML "syntax" | 15% |
UML is visually well organized and neatly drawn or electronically prepared. | 10% |
Appropriate names (Names are meaningful. Method names are verbs and instance variables and classes are nouns. Plural nouns are only used for collections.) | 10% |
Appropriate use of inheritance (Superclasses are used to prevent code duplication. Subclasses meaningfully extend the functionality of superclasses. Instance variables are not shadowed in subclasses.) | 10% |
Classes and methods are abstract where appropriate. | 10% |
Appropriate use of polymorphism (Using interfaces, superclasses or both.) | 10% |
Documentation provides a coherent defense of key design decisions. | 10% |
Documentation uses correct spelling, grammar etc. | 10% |
You must submit your finished project through Autolab by the deadline. Note that the Autolab submission tests will not be able to verify that your game elements are updated or drawn correctly or that your game logic is correct. Passing the Autolab tests will only mean that your code is formatted correctly and doesn't crash when it is executed. This makes it particularly important that you carefully test your code before submitting. Any submission that does not pass all of the automated tests will receive a score of 0.
Your submission should include all of the files necessary
to run your game except GameDriver.java
, Playable.java
and StdDraw.java
.
There are a huge number of improvements that could be introduced beyond the basic version of the game described above. Asteroids could break up on impact instead of being destroyed. Asteroids could be displayed as rock-like polygons instead of circles. Saucers could fire on the player's ship, etc.
We encourage you to experiment with as many of these improvements as you want, but the version you submit should strictly match the specification above.