CS 200 - Assignment 6

Due: Tuesday, November 27th by 11:59 PM

Shoot 'Em Up

In this assignment, you will implement a simple video game, similar to the classic game Space Invaders.

The approach will be very similar to Lab 22 and Assignment 5.  However, unlike those programs, there will be only one instance of the Scene data type, and your functions that work with the Scene will do so through pointers (which is the approach used in Lab 25).

Getting started

Download CS200_Assign6.zip.

If you have the Marmoset Add-in installed, you can import the zip file using File->Import....

If you do not have the Marmoset Add-in installed, create a new folder, extract the contents of the zip file into the folder, navigate into the folder using a file browser, and then double-click the solution file (CS200_Assign5.sln).

Add your code to the source file Invaders.c.

Your Task

Here is an annotated screen shot:

You can try my solution as an example of how the program should work:

CS200_Assign6.exe

You can press 'Q' or 'q' to quit the game.

The game works as follows:

The player can move a ship at the bottom of the screen left and right (using the arrow keys), and launch missiles using the space bar

The enemies move horizontally at the top of the screen.  (You can make them drop bombs for extra credit.)

Your program should support the following features:

At least 4 enemies which move horizontally (reversing direction when they reach an edge of the screen).

The player should be able to have at least 8 missiles in flight at once.

The enemies should explode when hit with a missile.

Your task is to add fields to the struct Scene data type, and implement the create_scene, render_sceneupdate_scene, and destroy_scene functions.

The create_scene function should return a pointer to a dynamically allocated instance of struct Scene.  You can create a new instance and assign it to a pointer variable as follows:

struct Scene *scene;

scene = (struct Scene *) malloc(sizeof(struct Scene));

You will need to initialize all of the fields before returning the pointer to the new Scene instance.

The render_scene function should draw one frame of the animation, based on the current locations, colors, and states of the player and enemies.

The update_scene function should

check to see if the player wants to move or fire a missile

move the enemies

move any missiles in flight

check for collisions between missiles in flight and enemies

The key parameter to update_scene will contain the special values LEFT_ARROW or RIGHT_ARROW if the player presses the left arrow or right arrow keys, respectively.  It will contain the space character code (' ') if the player presses the space bar (to fire a missile).

Note that the update_scene function works by modifying (in place) the struct Scene instance whose address is passed as its scene parameter.

The destroy_scene function frees the memory allocated for the struct Scene instance by create_scene.

Hints

You will need to define all of the required functions described above.  (Think about what parameter type(s) and return type they will each need to have.)

Here is a suggested approach for completing the program:

Add fields to struct Scene to represent the player.  Add code to create_scene to initially position the player ship in the middle of the bottom of the screen.  Add code to render_scene to draw the player ship.

Add code to update_scene to allow the player ship to move left and right.  Make sure the player ship doesn't move off the edge of the screen.

Add fields to struct Scene to represent missiles.  Add code to update_scene to allow the player to fire missiles, and to move in-flight missiles.  Missiles that move off the top of the screen should be changed so that they are no longer in flight.

Add fields to struct Scene to represent enemies.

Add code to create_scene to create enemies.  Add code to render_scene to draw the enemies on the screen.

Add fields to struct Scene to represent the movement of each enemy.  Add code to update_scene to move each active enemy.

Add code to update_scene to detect collisions between player missiles and active enemies.  An enemy that is hit by a missile should explode.  The explosion should be visible for some number of frames (suggestion: 40) and should be visually distinct from an active enemy.  Then an enemy is done exploding, it should be considered inactive (nonexistent).

You may find it useful to define struct Enemy and struct Missile data types.

Extra credit

Some features you can implement for extra credit:

Bombs: The enemies can drop bombs on the player.  If a bomb hits the player, the player ship explodes and the enemies win.

Score keeping: the player earns points for each enemy destroyed.  The current score should be displayed in a corner of the screen.

Multiple enemies per row: rather than assigning just one enemy per row (as I did in my solution), assign multiple enemies per row.

Advancing enemies: When an enemy reaches the edge of the screen, allow the enemy to move down one row and continue in the opposite direction:


The enemies win if one of them reaches the bottom row of the screen.

Particle-based explosions: When an enemy is hit with a missle, it breaks into several pieces and blows apart.  Each resulting fragment is independently animated.  Each fragment should start with an initial direction/velocity, and then accelerate towards the bottom of the screen (i.e., simulating gravity).

Submitting

If you have the Marmoset Add-in installed, you can submitonline automatically by using the Tools->Submit... menu item.  Just type in your Marmoset username and password and click Submit.  After a few seconds, you should see a dialog box informing you whether or not the submission was uploaded successfully.  If successful, the dialog will look like this:


If you do not have the Marmoset Add-in installed, or if the automatic online submission does not work, create a zip file containing your entire project and manually upload it to the Marmoset server.  (See the submission instructions for details.)