University of the West of England, Bristol

Department of Computer Science and Creative Technologies


UFCET3-20-2 Coding for Games Development

Semester One Assignment - Wolf Pack Game


On The Web

A web-based copy of this assignment, and all the necessary support files can be found on the web at:

    http://www.cems.uwe.ac.uk/~lrlang/CSharp/index.html

Formal Coursework Specification Document

    Click here to see the formal coursework specification

Scenario

The player is the commander of a warship in an ocean infested by enemy submarines. The submarines fire torpedos at the warship in an attempt to sink it. The commander's defenses are evasion, and to drop explosive depth charges. If a depth charge explodes close to a submarine then it is destroyed. The game ends when the ship is sunk.

Game Play

Starting the Game

The game displays the message "Press ESC key to start game"

The player presses ESC to start the game.

Playing the Game

The game background shows a sideways view of the sea surface, the water under the surface and the sea bed. The game starts with the warship floating on the surface. Soon after the game starts, the first submarine appears from either the left or right of the screen. The submarine moves to the other side of the screen at a fixed speed and depth.

The player presses the left or right arrow key to make the warship sail to the left or right. When the down arrow is pressed, a depth charge is thrown from the rear of the ship so that it travels through the air in an arc until it hits the water. The depth charge sinks until it reaches the submarine's depth when it explodes. If the submarine is close to the explosion then it is destroyed and the player's score is increased by 20. Only one depth charge can be deployed at a time.

Once the submarine has been destroyed, or has safely crossed from one side of the screen to the other, there will be a short pause and a new submarine will appear. The submarine appears at a random depth and randomly appears from the left or the right of the screen. Only one submarine can appear at a time.

Periodically, the submarine will launch a torpedo at the warship. The torpedo is aimed towards the centre position of the warship. The torpedo will continue towards this position even if the warship is moved, hence the player can evade destruction by moving the warship away from the torpedo's target point. If the torpedo strikes the warship then it sinks and the game ends. If the torpedo misses the ship then it is removed from the screen without exploding. Only one torpedo can be deployed at a time, but as the submarine crosses the screen there is sufficient time for it to shoot several torpedos. Torpedos have a limited rate of turn and hence the submarine can only launch a torpedo when the ship is ahead of, not above or behind, the submarine.

Ending the Game

The game ends when the warship is destroyed and the current submarine has moved off the edge of the screen (or has been destroyed).

The game background and score remain on the screen, with the message "GAME OVER" appearing in Red. This message remains for 2 seconds after which the game goes back to the "Starting the Game" state.

Supplied Resources

You are supplied with a C# project containing the following complete and incomplete classes:

The project is also pre-loaded with a number of images and sprite sheets for you to use:

    Download assignment resources:

Coding the Game Elements

Finite State Machines and Object Oriented Sprites

The behaviour of each sprite is described by a separate Finite State Machine which you are required to implement using the techniques described in Section 9 of your lecture notes.

You are also required to develop your code using the supplied Object Oriented sprite classes (BasicSprite, MovingSprite, VectoredSprite) which are described in Sections 7 and 8 of your lecture notes. Each sprite class should "extend" one of these of these classes, and provide (at least) a customised Update() method, which will be called from the Game1 class Update() method.

Important: The customised Update() method for each sprite must make an explicit call to base.Update() so that any default animation and sprite movement takes place!

Warship Sprite

The warship is the launching platform for the depth charge. While the user presses the Left or Right arrow key the warship moves in the corresponding direction. The sprite image must be horizontally flipped when the ship is moving from right to left. The ship is not allowed to sail off the edge of the screen.

C# Class Heading: class ShipSprite : BasicSprite

Design notes:

  1. Although this sprite moves, the ShipSprite class should inherit from the BasicSprite class rather than the MovingSprite class.
  2. To simplify the design, depth charge drops are triggered by the player from within the Game1 class.
  3. The class should provide a writeable public property named HitByTorpedo. Writing true to this property triggers transition T1.2.1 in the diagram below.
  4. To allow timing of transition T1.4, an int _timer field must be incremented on every call to ShipSprite Update(). The ship remains in the Destroyed state for a few seconds so that the game does not end abruptly.
  5. To perform the necessary animations, the sprite's Update() method must call base.Update() before returning.
  6. The supplied image shows the ship heading to the right; to reverse the image the inherited FlipHorizontal property must be set to true.

Finite State Diagram:

State Transition Trigger Actions Next State
Start
T1.1
No Trigger

 set X, Y to start position; set Show flag to true

Sailing
Sailing
T1.2.1
Hit By Torpedo

 start animation from frame 1 (ship breaking up)

Sinking
Sailing
T1.2.2
Right Arrow && not near right edge of screen
 add const velocity to X;
 do not flip sprite image
Sailing
Sailing
T1.2.3
Left Arrow && not near left edge of screen  subtract const velocity from X;
 flip sprite image
Sailing
Sinking

T1.3

Animation Finished
 start timer
Destroyed
Destroyed
T1.4
Time expired
 set Finished flag to true; set Show flag to false
End

Submarine Sprite

A submarine appears at a random depth at one side of the screen and sails at the same depth across to the other side of the screen. The game software randomly chooses whether or not the submarine appears from the left or the right. The torpedo launch is triggered when a timer reaches a threshold value (which you should choose) and the ship is ahead of the submarine's position. The timer is reset to zero after each launch so that subsequent torpedos may be launched when the first one has finished.

C# Class Heading: class SubmarineSprite : MovingSprite

Design Notes:

  1. This sprite moves at a fixed X velocity across the screen and should therefore inherit from the MovingSprite class described in your notes.
  2. Random numbers are used to choose the initial starting position (far left or right of screen) and Y position. The Y position must be chosen within the range: 250 to 550.
  3. To allow the timing of torpedo launches, a timer field must be incremented on every call to Update().
  4. A torpedo may only be launched when the ship is ahead of the submarine. You should use the suppied method to perform this check.

Finite State Diagram:

State Transition Trigger Actions Next State
Start T2.1.1 Random number < 0.5

 set X position to far left off edge of screen;
 set random Y position;
 set X Velocity to const positive value;
 do not flip image;
 set Show flag to true

Sailing
Start T2.1.2 Random number >= 0.5

 set start position to far right off edge of screen;
 set random Y position;
 set X Velocity to const negative value;
 flip image;
 set Show flag true

Sailing
Sailing T2.2.1 Edge of screen  set Finished flag to true; set Show flag to false End
Sailing T2.2.2 Hit by depth charge  start animation from frame 1 (sub breaking up);
 set velocity to zero
Sinking
Sailing T2.2.3 Ready to launch torpedo  tell torpedo to launch Sailing
Sinking T2.3 Animation finished  set Destroyed flag to true; start timer Destroyed
Destroyed T2.4 Time expired  set Finished flag to true; set Show flag to false End

Torpedo Sprite

The torpedo launch is triggered when the submarine sets the Launch property to true. The torpedo should remember the current position of the warship as its target X and Y. The torpedo's starting position is the torpedo launch tube on the submarine, which varies depending on whether the submarine is facing left or right.

On each update, the torpedo should calculate the angle from its current position to the target position, and then move a short distance in that direction; however to make the torpedo look more realistic it may only change its angle by a short amount each update. This causes the torpedo to leave the submarine in a horizontal direction and then move in an arc until it's heading directly towards the target point.

C# Class Heading: class TorpedoSprite : VectoredSprite

Design Notes:

  1. The TorpedoSprite class should inherit from the VectoredSprite class described in your lecture notes.
  2. The class should provide a writeable public property named Launch. Writing true to this property causes the torpedo run to start (see transition T3.1.1 and T3.1.2 in figure below).
  3. The class should provide a public Running property which returns true when the torpedo is in the Running state.
  4. If the torpedo hits the ship sprite, then it should set the ship's HitByTorpedo property to true.

Finite State Diagram:

State Transition Trigger Actions Next State
Start T3.1.1 Launch && Sub Facing Right  set start position to submarine plus X offset for
  torpedo tube position;
 set Angle to Math.PI/2;
 set target X, Y to ship X, Y position;
 set Velocity to const value;
 set Scale to 0.5;
 set Show flag to true
Running
Start T3.1.2 Launch && Sub Facing Left  set start position to submarine minus X offset for
  torpedo tube position;
 set Angle to -Math.PI/2;
 set target X, Y to ship X, Y position;
 set Velocity to const value;
 set Scale to 0.5;
 set Show flag to true
Running
Running

T3.2.1

Hit the ship  set the ship's HitByTorpedo flag to true;
 start animation from frame 1 (explosion);
 set Scale to 1;
 set Velocity and Angle to zero
Hit Target
Running T3.2.2 Reached target point but did no hit the ship  set Show flag to false;
 set Finished flag to true
End
Running T3.2.3 Passed edge of screen  set Show flag to false;
 set Finished flag to true
End
Running T3.2.4 (else no other trigger)

 calculate angle to target;
 limit change of angle if change is too great

Running
Hit Target T3.3 Animation finished  set Show flag to false;
 set Finished flag to true
End

Depth Charge Sprite

A depth charge is "dropped" (or, more accurately, thrown backwards from the rear of the ship) when the player presses the Down arrow key. It travels through the air in an arc until it drops into the sea. Once in the sea, it sinks vertically downward until it reaches the current submarine's Y position, when it explodes. The submarine is destroyed if it is within the range of the explosion, or moves into range while the explosion animation is in progress.

C# Class Heading: class DepthChargeSprite : VectoredSprite

Design notes:

  1. The sprite's movement through the air is achieved by setting a fixed Velocity and Rotation for the VectoredSprite class. When the depth charge has turned through 180 degrees, the Rotation should be changed to zero and the Angle changed to Math.PI, forcing it to move downward through the sea.
  2. The class should provide a writeable public property named Drop. Writing true to this property causes the depth charge launch/drop sequence to start (see transition T4.1.1 and T4.1.2 in figure below).

Finite State Diagram:

State Transition Trigger Actions Next State
Start T4.1.1 Drop && ship facing right

 set start position to ship minus X offset of
  launcher position;
 set Angle to 0.0; // Upwards
 set Velocity to const value;
 set Rotation to negative const value;
 set Scale to 0.3;
 set Show flag to true

In Air
Start T4.1.2 Drop && ship facing left  set start position to ship plus X offset of
  launcher position;
 set Angle to 0.0; // Upwards
 set Velocity to const value;
 set Rotation to positive const value;
 set Scale to 0.3;
 set Show flag to true
In Air
In Air T4.2.1 Y >= sea level  set Angle to Math.PI;
 set Rotation to zero;
 set Velocity to const value
Sinking
Sinking T4.3 Y >= submarine Y  start explosion animation;
 set Velocity to zero; set Angle to zero;
 set Scale to 1.0
Exploding
Exploding T4.4.1 Submarine X in range
of explosion
set submarine HitByDepthCharge flag to true Exploding
Exploding T4.4.2 Animation finished set Finished to true; set Show to false End

Boilerplate Game1 class

The Update() method in the Game1 class oversees the whole game process, whilst the Draw() method sequences the drawing order for the background, sprites and score.

The code within the Update() method is (believed to be) correct, but each line has been commented out to allow separate development of each sprite class without causing compilation errors. As you work on each sprite class you will need to remove the comment markers to allow the sprite to operate correctly. At the same time you will need to add statements to the Draw() method so you can see each sprite in action.

Finite State Diagram:

State Transition Trigger Actions Next State
Insert Coin T0.1 User presses ESC
(simulates insert coin)
 Initialise all game variables and objects Playing
Playing T0.2.1 Ship destroyed && no submarines on screen  Start timer Game Over
Playing T0.2.2 (no trigger)

 Game play continues Playing
Game Over T0.3 Timer running for
2 seconds
 (none) Insert Coin

Whilst the game is in each state, the Draw() method should display graphics as follows:

State Draw() method displays
Insert Coin  "Press ESC key to start game"
Playing  Normal game operation including score
Game Over  Normal game background, "GAME OVER" and final score

What You Must Do

Using XNA 3.1, you must complete the supplied project so that the game operates as described above. Your code must conform to these guidelines:

Marks Available

Marks are available for each class you complete and get working. The following table shows the maximum marks available for each class - partial marks will be given if appropriate:

    Class C# Coding Comments Choice of Names Use of consts
    ShipSprite 10 4 3 3
    SubmarineSprite 10 4 3 3
    TorpedoSprite 10 4 3 3
    DepthChargeSprite 10 4 3 3
    Game1 10 4 3 3

Submitting Your Work

To submit your work you should copy the entire top-level project folder onto a full-size CD-ROM, DVD-ROM or USB memory stick and submit it with a coursework submission form.

I recommend the following ways to submit your work:

  1. Use a special purpose folder with a section for a CD/DVD case. This is the preferred option.
  2. Use a self adhesive CD/DVD envelope, which you stick to the back of the submission form and then put into a clear A4 plastic envelope.
  3. Use a normal rigid CD/DVD case which you blu-tac to the back of the submission form and then put into a clear A4 plastic envelope.

If you use option 2 or 3 then you should seal the A4 clear envelope using two or three paperclips across the top. Do NOT use sticky tape or staples.

The following submissions are completely unacceptable:

Bob Lang
October 2010