Assignment 2
COMP 106



For this assignment we will continue building our DisAsteroids computer game. The main goal will be to create a data structure to support a spaceship, asterioids, and an occasional alien or two. You will provide a paintComponent() callback routine that can draw all of these objects from your data structure. Your program will need to create a main window and a canvas window for drawing.

Game Objects

GameElement Baseclass: All of the visual objects in our game (asteroids, spaceships, and aliens) share some important commonalities -- they all have a position and a velocity vector. In the game, outer space is simulated by a warped 2D plane -- warped because if an object moves off one end of the screen it appears again on the other side. An object's position is represented by an XY coordinate pair. An object's velocity is represented by a vector that specifies how far it moves in the X and the Y direction per unit time.

Since all objects share these commonalities, it makes sense to create an abstract base class to represent them. This base class should have a constructor to set the initial position and velocity, and it should have an abstract draw() method that takes a Graphics2D object as a parameter.

Spaceship Subclass: Next, create a class for your spaceship. This class will extend the GameElement base class and may add some additional instance variables (such as "lives" remaining). The Spaceship class should override the superclass's draw routine and should have a constructor that specifies initial values for its instance variables.

Asteroid Subclass: Create a subclass to represent an asteroid. Override the draw method and add some additional instance variables for things like size and color.

Alien Subclass: Create a subclass to represent alien spaceships that occasionally fly across the screen and shoot at your spaceship.

Game Class

You should also provide an object that keeps track of the overall state of the game and draws the main game canvas. The game object will maintain data that applies to the game as a whole and will create and maintain all of the game objects (spaceship, asteroids, and aliens). The game object will also create and maintain the drawing canvas and provide the main redrawing routine for it.

You will want to provide some sort of data structure (a list or an array should suffice) that will store all of the game objects. This data structure should use references to the GameElement base class rather than to specific subclasses. Your Game.paintComponent() method will then simply cycle through the list and ask each object to draw itself in turn.

All drawing must be done inside the paintComponent() callback, which may be called at any time. For example, it will be called when the window is exposed or resized; it may also be triggered manually when the state of the game changes due to a user command. Your routine should always be prepared to draw the game from scratch, using data you have stored inside your objects.

Keyboard Input

Your game should be playable using keyboard keys. These can be the arrow keys, alphanumeric keys, or any other plausible set of keys. For this assignment, choose a set of keyboard keys to control the spaceship (rotate in place left or right, accelerate, decelerate, fire a bullet, and warp to a random location on the screen). Be sure to document these keys in your readme file. Create a keyboard listener that updates the spaceship and then redraws the drawing area when any of your keys are pressed.

As discussed in class, note that getting keyboard events in the canvas window requires some extra programming, especially if you have any other widgets or panels beside the canvas. You need to make sure your canvas area, rather than some other widget, has the keyboard "focus" in order to receive keyboard events. To do this, create a mouseEntered() [or mousePressed()] callback for your canvas, and, each time it is called, it should call YOUR_CANVAS.requestFocus(). This will assign the keyboard focus to the canvas each time the mouse enters it [or clicks in it]. You can also use a FocusListener.

Main Program

Your main program, which is a public static method in your class called Main, should simply instantiate an object of class Main. Your constructor for Main will then set up your window, instantiate and initialize the objects you need, such as the Game object (which in turn instantiates the spaceship, asteroids, and aliens), show the window, and then let the window system take over and wait for callbacks. The window should close and the application should quit when a user clicks on the close icon (the "X" in the far upper-right corner of the window title bar).

Once the program is running, it will simply display the drawing area, redrawing it as necessary, and waiting for callbacks from user input on the keyboard.

Program Design and Practices

Your program design should exploit the features of object-oriented programming (encapsulation of code and data, support for abstract data types, polymorphism/overloading, inheritance). In particular, object-oriented programming provides us a good way to handle the various data needed in callback routines. You should use objects to encapsulate each interactive widget with the routines and data you need to use it.

You should provide an object for each interactive widget or small group of widgets you create. That object should hold anything you need to remember about the widget from one callback to another, all the data pertinent only to the command for that widget or that you need to operate this control, (including, in most cases, a pointer to the graph or other outside object to perform the actual action the user requested), and the widget's own listener callback routines.

If you have several widgets that share some behavior or properties, you should organize your objects into an appropriate inheritance hierarchy.

You will have other data that must be accessed by several widgets, particularly shared information about the state of the program or global information about the state of the user interface. Provide additional classes and objects for holding this kind of information.

Remember to trigger your drawing to repaint itself explicitly whenever one of your commands causes a change in the state of the graph that should be reflected on the screen. And remember that the way to change the screen is first to change the data stored in the Graph or other classes and then to trigger the repaint.

You should follow these general Java programming practices:

And, finally, for uniformity please name your Java class that has your main program in it Main, in file Main.java

Design Documentation

In addition to your program, submit documentation about the design of your system in these forms:

Submit this documentation electronically in text form. Include it as part of the readme file that you submit with your assignment.

These diagrams may be trivial for this assignment, but will become more interesting with later assignments.

Grading

  1. Creates an abstract GameElement superclass which encapsulates an object's velocity and position (1 point)
  2. Creates a Spaceship subclass with a draw method and some additional instance variables (1 point)
  3. Creates an Asteroid subclass with a draw method and some additional instance variables (1 point)
  4. Creates an Alien subclass with a draw method and some additional instance variables (1 point)
  5. Provides a Game object with a game object data structure, other game instance variables, and a paintComponent() routine which draws the drawing area (1.5 points)
  6. Provides a listener to Keyboard input that redraw the drawing area in response to user input (1 points)
  7. Quits the application when the main window is closed (0.5 point)
  8. Follows all guidelines in Program Design and Practices section (0.5 point)
  9. Presents complete and clear design documentation (1 point)
  10. Adds something more, does something new, or significantly surpasses any of the preceding criteria (1.5 points)

As in the previous assignment, note that creating excellent, nontrivial software requires creativity beyond what your customers, or professor, can explicitly mandate. In general, great software satisfies a set of general requirements or requests, and then adds something beyond that. Grading for the assignments will reflect this fact. Satisfying exactly the bare minimum for each assignment will merit a grade of approximately 75% or 85%, depending on the specific assignment. The remaining points will be awarded for additional work that adds the special something. This is not necessarily easy to do. You will be both the software designer and the software developer in this course. It's not just the implementation that is important, but also the design of the application. If you do this, include a brief description in your readme file, as noted in the submission instructions.