CS21 Lab 11: SpaceBlaster

Due Saturday night, April 27 Thursday night, May 2

Make sure all programs are saved to your cs21/labs/11 directory. Files outside this directory will not be graded.

$ update21
$ cd ~/cs21/labs/11

Topics for this assignment


So far in this course we have used many different types of objects (Circle, Point, lists, strings, Zipcode, Channel, ...) but you haven't defined your own classes. The goal of this lab is to practice writing your own classes, with constructors, attributes, and methods.

In the file spaceblaster.py, you will implement a game to navigate a starship across space, destroying asteroids along the way. Be careful---hitting an asteroid will damage your starship, and it's the only one you have!

SpaceBlaster! more SpaceBlaster!

High-level Specifications:

To complete this assignment, you need to implement two classes: Asteroid and Starship. Asteroids come in different sizes, move in different directions, and at different speeds. The starship comes equipped with a high-powered laser that can blast asteroids to smithereens, but only when the asteroid is directly in front of the starship. The laser is so powerful it can blow through entire asteroids, destroying everything in its path. The player scores one point for each destroyed asteroid; play continues until the starship collides with an asteroid.

Breaking things up into classes

This game may look hard to program at first glance, but by breaking the program up into classes and testing each class incrementally, it will be relatively strightfoward to implement.

1. The Asteroid Class

First, write and test the Asteroid class that has the methods shown below. We encourage you to test each method as you write them. For example, write the constructor (__init__), then write some test code to make a graphics window and create an Asteroid object. Make sure its size, color, and position look correct. Then add the move() method, and add more test code to move the asteroid in the right direction.

Constructor __init__(self, win)

Your constructor should:

move method: move(self)

Note: this move() method will call the Zelle graphics move() method to move the Circle object. It's OK that it has the same name.

offScreen method: offScreen(self)

destroy method: destroy(self)

getBoundary method: getBoundary(self)

Here is a video showing a simple test of the Asteroid class. It creates an Asteroid and moves it until it is off-screen.

2. The Starship Class

Next, write and test the Starship class that has the methods shown below. This class will craete the starship object itself (a rectangle for the main body with two smaller rectangles to represent tail fins), as well as the methods needed to move the starship, fire the laser, and decide if it collides with an Asteroid.

Constructor __init__(self, win)

First, implement the constructor method __init__(self, win). This method has an input parameter win, a GraphWin object. It should create a Rectangle object for the body of your starship, two smaller rectangle objects to represent tail fins, and draw the rectangles on the screen. In addition, the Starship has a speed and direction. These should be initially zero (the ship is at rest) and ("Right") respectively. Other specifications lie below:

move method: move(self, new_direction)

The move() method moves the Starship a small distance, depending on its current speed and direction. A Starship's direction should be one of "Up", "Down", "Left", "Right". When the move method is called, two steps must be taken. First, update the direction and speed. Second, move the starship in the new direction according to the updated speed.

collide method: collide(self, asteroid)

The collide() method takes an asteroid object as input and returns True if the starship has collided with this asteroid. There could be two reasons why the starship and asteroid collide---either the starship moves into the asteroid, or vice versa. To make things a little simpler, we've created a helper function intersect(rect, circ) in a sb_utils library. The intersect() function has two input parameters: a Rectangle object and a Circle object. It returns True if the two objects intersect. To use this method, first import the cs21s19 library:

from cs21s19 import intersect

The Starship class contains three Rectangles; the Asteroid class is represented with a Circle. To see if the Starship collides with the Asteroid, check to see if any part of the starship intersects with the asteroid.

fire method: fire(self, asteroids)

The fire() method has one input parameter in addition to self: asteroids, a list of Asteroid objects. The purpose of this method is to handle what happens when the Starship fires its laser gun. To represent the laser, draw a thin red Line from the right side of the Starship to the end of the graphics window.

To determine if an asteroid has been hit by the laser, check to see if two things occur: (i) the center of the asteroid is to the right of the Starship's center, and (ii) the starship's center's y-coordinate is within a radius of the y-coordinate of the asteroid.

If an asteroid does get hit, it is destroyed.

Testing the Starship class

Use incremental development and testing as you program your Starship class. First, implement the constructor and make sure your Starship appears on the window. Then, implement the move method, save your code, and test it by calling move several times. Does the Starship move in the way you expect? Finally, create some Asteroid objects, and move the Starship until it collides with an Asteroid. Does the starship correctly detect collisions?

Here are some sample test videos of the Starship class:

3. Writing the main program

Your main program should create a starship and an initial set of asteroids, and then loop until either the starship collides with an asteroid or the user enters q.

Inside each iteration of the game loop, you should:

Once the game ends, print a status message in the GraphWin object describing the user's score and why the game ended; e.g., user quit or collided with an asteroid.

4. Extra Challenges

There are many possible extra challenges for this assignment if you're inclined to make this lab truly out of this world. Here are some suggestions:


Once you are satisfied with your programs, fill out the questionnaire in QUESTIONS-11.txt. Then run handin21 a final time to make sure we have access to the most recent versions of your file.