retro game...retro game event driven programming end of module assignment, hnd computing and systems...

31
Retro Game Event Driven Programming End Of Module Assignment, HND Computing and Systems Development Year 1, 2011. Chichester College. Author: Alex Hughes Develop a 2D game with movement and animation of screen objects in the style of the classic retro-game “space invaders”. The game must include more than one window and should include appropriate features that will make it a professional windows application implementing standard windows conventions.

Upload: others

Post on 19-Sep-2020

5 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Retro Game...Retro Game Event Driven Programming End Of Module Assignment, HND Computing and Systems Development Year 1, 2011. Chichester College. Author: Alex Hughes Develop a 2D

Retro Game Event Driven Programming End Of Module Assignment, HND Computing and Systems

Development Year 1, 2011. Chichester College. Author: Alex Hughes

Develop a 2D game with movement and animation of screen objects in the style of the classic retro-game “space invaders”.

The game must include more than one window and should include appropriate features that will make it a professional

windows application implementing standard windows conventions.

Page 2: Retro Game...Retro Game Event Driven Programming End Of Module Assignment, HND Computing and Systems Development Year 1, 2011. Chichester College. Author: Alex Hughes Develop a 2D

Deliverables

Design Documentation

Space Invaders 2: Brief

I am aiming to recapture a version of the original Taito Space invaders game. It’s been a while since I played it so I may not

have remembered everything.

On starting the application the screen will be set up and a message encouraging the user to press space to start.

The game will start with 100 or so aliens in a grid formation at the top of the screen. The will move from side to side as a

grid going down a row when they reach the screen edge. They will drop bombs on the gunner and the gunner will shoot

bullets at them. The original only allowed 1 bullet at a time but I am going to have multiple bullets at any one time (and

multiple bombs)

There will also be 4 shields to hide behind which will degrade as bombs hit them. There should be the facility for the gunner

to shoot through the shields and create a pillar box.

Invaders will come in 3 animated types and will attract different numbers of point when shot. They will also have varying

numbers of lives so may have to take up to 3 hits before disappearing.

When all the invaders are killed, there will be an end of level bonus of 1000 points times the level number. A new level will

start with aliens moving faster and dropping more bombs. New shields will be provided.

If the gunner ship gets hit by a bomb a life will be lost. Spare ships are displayed at the bottom of the screen. Level and

score are displayed at the top of the screen.

The game ends when all lives are lost. If the score is greater than the high score variable the high score is updated.

Help will be available via a help menu. There will also be an about screen.

Design stages.

The first step was Space Invaders 1. This used images created in the xaml and a single bullet that disappeared when it hit

something or went off the screen and was moved back to the ship when required again.

Page 3: Retro Game...Retro Game Event Driven Programming End Of Module Assignment, HND Computing and Systems Development Year 1, 2011. Chichester College. Author: Alex Hughes Develop a 2D

Here I am using the graphics provided having crudely cut them out from the jpeg of all the images combined:

Compared to the original 8*8 sprites these images are enormous and not animated.

Credit is due to David for finding the original Taito printed background (I think the Aliens were superimposed using a glass

sheet.)

Page 4: Retro Game...Retro Game Event Driven Programming End Of Module Assignment, HND Computing and Systems Development Year 1, 2011. Chichester College. Author: Alex Hughes Develop a 2D

Space invaders 1 showed visibility and hidden properties for image elements and how to do a hit test and the GetLeft and

SetLeft features of the WPF interface.

I wanted to go further and dynamically draw aliens and this key stage was achieved in space Invaders 2a.

This game was recycled from spaceInvaders 1 and the key breakthrough was the use of bitmap images as variables.

BitmapImage bitInvader1 = new BitmapImage(); bitInvader1.BeginInit(); bitInvader1.UriSource = new Uri("invader1.png", UriKind.Relative); bitInvader1.EndInit();

Once you have this something like this is possible.

Image imgInvader = new Image(); imgInvader.Source = bitInvader1; cnvSpace.Children.Add(imgInvader); Canvas.SetLeft(imgInvader, 400);

Page 5: Retro Game...Retro Game Event Driven Programming End Of Module Assignment, HND Computing and Systems Development Year 1, 2011. Chichester College. Author: Alex Hughes Develop a 2D

And with a couple of for loops a screen full of invaders was created.

Space Invaders 2a had the invaders moving but there was no game functionality. This was achieved in the latest version :

Space Invaders 2.

Space Invaders 2: Schema. Space Invaders 2 uses User Controls to create the invaders bullets and bombs. The gunner is a standard image.

The user controls are:

Invader : UserControl

properties:

public int flavour = 1; public int lives = 1; public int points = 10; //the class invader has three properties: flavour (which kind of alien it is) //lives (how many lives it has) //points (how many points you get for killing it)

Bomb : UserControl

methods:

public void MoveBomb(int intBombSpeed)

Bullet : UserControl

methods:

public void MoveBullet(int intBulletSpeed)

shieldElement : UserControl

properties:

public int intLives = 3;

These allow us to create game elements either from the toolbar or from within the c#.

The next key items are the typed lists

List<Invader> Aliens = new List<Invader>(); List<Bomb> Bombs = new List<Bomb>(); List<Bullet> Bullets = new List<Bullet>(); List<shieldElement> Shields = new List<shieldElement>();

The shields are actually made from many tiny rectangles each of which is a sprite in its own right.

These keep track of all the game items that are in play and in the code we will perform operations on each one in turn.

Page 6: Retro Game...Retro Game Event Driven Programming End Of Module Assignment, HND Computing and Systems Development Year 1, 2011. Chichester College. Author: Alex Hughes Develop a 2D

Because you cannot delete an item from a list whilst executing a foreach loop on it there are also the dead lists of items

that have been annihilated on the particular pass and must be removed when it is done.

List<Invader> DeadAliens = new List<Invader>(); List<Bullet> DeadBullets = new List<Bullet>(); List<Bomb> DeadBombs = new List<Bomb>(); List<shieldElement> DeadShieldElements = new List<shieldElement>();

Finally there is a list of the spare ships so that when one dies you can just delete the most recently added.

List<Image> Lives = new List<Image>();

All the elements need to be placed on a canvas. That is

<Canvas Name="cnvSpace" Width="722" Margin="16,12,16,0" Height="574" VerticalAlignment="Top">

There are labels for Score, High Score, Level, Game Over, Press Space to Start, Level Completed.

The images to be used must be loaded into the memory from the embedded files they go into

BitmapImage bitInv1a = new BitmapImage(); BitmapImage bitInv1b = new BitmapImage(); BitmapImage bitInv2a = new BitmapImage(); BitmapImage bitInv2b = new BitmapImage(); BitmapImage bitInv3a = new BitmapImage(); BitmapImage bitInv3b = new BitmapImage();

for three types of 2 step animated aliens.

BitmapImage bitBullet = new BitmapImage(); BitmapImage bitGunner = new BitmapImage(); for the defender and bullets BitmapImage bitshielda = new BitmapImage(); BitmapImage bitshieldb = new BitmapImage(); BitmapImage bitshieldc = new BitmapImage(); Three step shield breakdown.

All images were made from pixels in Gimp because the provided images had jpeg errors and were not animated.

DispatcherTimer myTimer = new DispatcherTimer();

The timer ticks every 20 milliseconds to run the game loop through. With the following event handler:

myTimer.Tick += new EventHandler(myTimer_Elaspsed); private void myTimer_Elaspsed(object source, EventArgs e) { gameLoop(); }

The KeyDown and KeyUp event handlers

private void Window_KeyDown(object sender, KeyEventArgs e) {…} private void Window_KeyUp(object sender, KeyEventArgs e)

{…}

which control boolean variables for the keys:

Page 7: Retro Game...Retro Game Event Driven Programming End Of Module Assignment, HND Computing and Systems Development Year 1, 2011. Chichester College. Author: Alex Hughes Develop a 2D

bool blnLeft = false; bool blnRight = false; bool blnSpace = false;

There is a random number generator so that the invaders drop bombs (initially) at a probability of 1 in 1000 drops per

invader per tick.

Random randomObj = new Random();

So the main game loop

private void gameLoop() { moveAliens(); moveGunner(); //only allows a bullet to be fired if it is a certain number of // timer ticks after the last bullet was fired if ((blnSpace)&&(intBulletFired==intBulletRecharge)) { fireBullet(); intBulletFired=0; } // increments intBulletFired if it is below the threashold. if (intBulletFired<intBulletRecharge){intBulletFired++;} //move bullets each bullet will be moved up a certain number of pixels moveBullets(); //invaders drop bombs invadersDropBombs(); //move bombs moveBombs(); //runs through the various hit tests doHitTests(); //deletes bullets that have gone off the top of the screen loseBulletsOffScreen(); //deletes bombs that have gone off the bottom of the screen loseBombsOffScreen(); //animates the aliens if (intAniCount == intSwitch) { animateAliens(1); } if (intAniCount == intSwitch * 2) { animateAliens(2); intAniCount = 0; } intAniCount++; }

Page 8: Retro Game...Retro Game Event Driven Programming End Of Module Assignment, HND Computing and Systems Development Year 1, 2011. Chichester College. Author: Alex Hughes Develop a 2D

The Game.

The game is released Open Source (except for look and feel owned by Taito) and is available on my website at

http://www.alexishughes.net76.net

The commented code.

This runs to about 900 lines with comments and the project folder was too large to put on my site. It is available at my

skydrive on https://skydrive.live.com/redir.aspx?cid=29e362046ec077d9&resid=29E362046EC077D9!145

Invader.xaml.cs … namespace SpaceInvaders2 { /// <summary> /// Interaction logic for Invader.xaml /// </summary> public partial class Invader : UserControl { //the class invader has three properties: flavour (which kind of alioen it is) //lives (how many lives it has)

Page 9: Retro Game...Retro Game Event Driven Programming End Of Module Assignment, HND Computing and Systems Development Year 1, 2011. Chichester College. Author: Alex Hughes Develop a 2D

//points (how many points you get for killing it) //it does not contain a method for moving it as the invaders are moved as a whole. public int flavour = 1; public int lives = 1; public int points = 10; public Invader() { InitializeComponent(); } } }

bullet.xaml.cs … namespace SpaceInvaders2 { /// <summary> /// Interaction logic for Bullet.xaml /// </summary> public partial class Bullet : UserControl { public Bullet() { InitializeComponent(); } //the bullet has a moveBullet method which moves it up by the number of pixels specified public void MoveBullet(int intBulletSpeed) { Canvas.SetTop(this, Canvas.GetTop(this) - intBulletSpeed); } } }

bomb.xaml.cs … namespace SpaceInvaders2 { /// <summary> /// Interaction logic for Bomb.xaml /// </summary> public partial class Bomb : UserControl { public Bomb() { InitializeComponent(); } //the bomb has a method that moves it down each move. public void MoveBomb(int intBombSpeed) { Canvas.SetTop(this,Canvas.GetTop(this)+intBombSpeed); } } }

Page 10: Retro Game...Retro Game Event Driven Programming End Of Module Assignment, HND Computing and Systems Development Year 1, 2011. Chichester College. Author: Alex Hughes Develop a 2D

MainWindow.xaml using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Windows; using System.Windows.Controls; using System.Windows.Data; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Imaging; using System.Windows.Navigation; using System.Windows.Shapes; using System.Windows.Threading; using System.Threading; namespace SpaceInvaders2 { /// <summary> /// Interaction logic for MainWindow.xaml /// </summary> public partial class MainWindow : Window { //setting up the variables DispatcherTimer myTimer = new DispatcherTimer(); //int refresh rate is th number of milliseconds between each iteration of the game loop. int intRefreshRate = 20; //blnleft, blnright, blnspace represent whether the keys are being pressed and are turned //on and off (true/false) by the keyup keydown events in mainWindow bool blnLeft = false; bool blnRight = false; bool blnSpace = false; //bln game started inicates whether the game is in play bool blnGameStarted = false; //intscore is the current score int intScore = 0; //intHighScore is the highest score of the session. int intHighScore=0; //intLives is the number of lives the play has left. (note this could be done by counting the Lives list //of images) int intLives= 5; //dblMaxLeft and dblMaxRight find the furthest left and furthest right of the aliens and gets their //GetLeft property //(the aliens don't change direction until the outside one hits the edge of the screen) double dblMaxLeft; double dblMinLeft; //blnMoveInvDown is true when the aliens reach the edge of the screen when they move down bool blnMoveInvDown = false; //dblInvSpeed is the number of pixels each alien moves each tick double dblInvSpeed = 4; // dblInvMove is how many pixels they move down when they reach the edgeof the screen. double dblInvMove = 4; // dblCurrentleft is the GetLeft property of the gunner. double dblCurrentLeft = 0; // dblGunnerSpeed is the number of pixel the gunner moves per tick. double dblGunnerSpeed = 10; //int aniCount is the number of ticks between changing the image of the invaders int intAniCount = 0; int intSwitch = 15; //intBulletRegcharge is the number of ticks until you can fire another bullet. int intBulletRecharge=7; //intBulletFired is the number of ticks since the last bullet was fired. int intBulletFired=0;

Page 11: Retro Game...Retro Game Event Driven Programming End Of Module Assignment, HND Computing and Systems Development Year 1, 2011. Chichester College. Author: Alex Hughes Develop a 2D

//intBulletSpeed is the number of pixels the bullet moves each time int intBulletSpeed = 10; //intBombSpeed is the number of pixels the bomb moves each tick int intBombSpeed = 2; //intBombRate. Every tick, each invader picks a random number between 0 and intBombRate. //if this number is 1 then the invader creates a new bomb instance and drops it. int intBombRate = 1000; //intLevel is the current level (initially 1) int intLevel; //intBonus is the number of bonus points granted for finishing the level. int intBonus; //initialize bitmaps for the user controls. //bitshielda,b,c are the shield element (a small rectangle) that degrades with the number of hits. BitmapImage bitshielda = new BitmapImage(); BitmapImage bitshieldb = new BitmapImage(); BitmapImage bitshieldc = new BitmapImage(); //bitInv1a..3b are 2step animations for 3 types of invaders. BitmapImage bitInv1a = new BitmapImage(); BitmapImage bitInv1b = new BitmapImage(); BitmapImage bitInv2a = new BitmapImage(); BitmapImage bitInv2b = new BitmapImage(); BitmapImage bitInv3a = new BitmapImage(); BitmapImage bitInv3b = new BitmapImage(); BitmapImage bitBullet = new BitmapImage(); BitmapImage bitGunner = new BitmapImage(); //random number generator Random randomObj = new Random(); //Text lists of objects for the game aliens bombs and bullets List<Invader> Aliens = new List<Invader>(); List<Bomb> Bombs = new List<Bomb>(); List<Bullet> Bullets = new List<Bullet>(); //because you cannot remove items from a list whilst you are working through it a dead list is created //the dead objects are then removed from the list after all the hit tests have completed. List<Invader> DeadAliens = new List<Invader>(); List<Bullet> DeadBullets = new List<Bullet>(); List<Bomb> DeadBombs = new List<Bomb>(); //the shields are actually made of many rectangles which each have 3 lives and are contained in a list. List<shieldElement> Shields = new List<shieldElement>(); List<shieldElement> DeadShieldElements = new List<shieldElement>(); //finally the spare gunner ships are stored in this list to make it easy to remove the newest one. List<Image> Lives = new List<Image>(); public MainWindow() { //draw the MainWindow InitializeComponent(); //these set up bitmap variables for all the graphics the program will use from the embedded .png //files bitshielda.BeginInit(); bitshielda.UriSource = new Uri("shielda.png", UriKind.Relative); bitshielda.EndInit(); bitshieldb.BeginInit(); bitshieldb.UriSource = new Uri("shieldb.png", UriKind.Relative); bitshieldb.EndInit(); bitshieldc.BeginInit(); bitshieldc.UriSource = new Uri("shieldc.png", UriKind.Relative); bitshieldc.EndInit(); bitInv1a.BeginInit(); bitInv1a.UriSource = new Uri("inv1a.png", UriKind.Relative);

Page 12: Retro Game...Retro Game Event Driven Programming End Of Module Assignment, HND Computing and Systems Development Year 1, 2011. Chichester College. Author: Alex Hughes Develop a 2D

bitInv1a.EndInit(); bitInv1b.BeginInit(); bitInv1b.UriSource = new Uri("inv1a.png", UriKind.Relative); bitInv1b.EndInit(); bitInv2a.BeginInit(); bitInv2a.UriSource = new Uri("inv2a.png", UriKind.Relative); bitInv2a.EndInit(); bitInv2b.BeginInit(); bitInv2b.UriSource = new Uri("inv2b.png", UriKind.Relative); bitInv2b.EndInit(); bitInv3a.BeginInit(); bitInv3a.UriSource = new Uri("inv3a.png", UriKind.Relative); bitInv3a.EndInit(); bitInv3b.BeginInit(); bitInv3b.UriSource = new Uri("inv3b.png", UriKind.Relative); bitInv3b.EndInit(); bitBullet.BeginInit(); bitBullet.UriSource = new Uri("bullet.png", UriKind.Relative); bitBullet.EndInit(); bitGunner.BeginInit(); bitGunner.UriSource = new Uri("gunner.png", UriKind.Relative); bitGunner.EndInit(); //adds a new Event Handler for myTimer myTimer.Tick += new EventHandler(myTimer_Elaspsed); myTimer.Interval = TimeSpan.FromMilliseconds(intRefreshRate); //initialize the game drawAliens(); drawSpareGunners(); drawShields(); } //every time the myTimer has a tick event, call the gameLoop() method private void myTimer_Elaspsed(object source, EventArgs e) { gameLoop(); } //The startGame() method hides the Game Over and press space to begin labels and initializes the game //board. private void startGame() { lblGameOver.Visibility=Visibility.Hidden; lblPressSpace.Visibility = Visibility.Hidden; myTimer.Start(); intScore = 0; intLevel = 1; lblScore.Content = "Score : " + intScore.ToString(); lblLevel.Content = "Level : " + intLevel.ToString(); // a random number is generated between 0 and BombRate for each alien at each clock tick. // If the number is a 1 a bomb is dropped // when the player goes up a level BombRate is reduced by 10% so there are more bombs.

Page 13: Retro Game...Retro Game Event Driven Programming End Of Module Assignment, HND Computing and Systems Development Year 1, 2011. Chichester College. Author: Alex Hughes Develop a 2D

intBombRate = 1000; //dblInvSpeed is the number of pixels the alien moves each loop. dblInvSpeed = 4; //if the game is being re-started all invaders, spare ships and shields will be re-drawn. foreach (Invader thisInvader in Aliens) { cnvSpace.Children.Remove(thisInvader); } Aliens.Clear(); drawAliens(); foreach (Image thisLife in Lives) { cnvSpace.Children.Remove(thisLife); } Lives.Clear(); drawSpareGunners(); foreach (shieldElement thisShieldElement in Shields) { cnvSpace.Children.Remove(thisShieldElement); } Shields.Clear(); drawShields(); } //stops the game private void stopGame() { myTimer.Stop(); } //this is the main game loop private void gameLoop() { moveAliens(); moveGunner(); //only allows a bullet to be fired if it is a certain number of // timer ticks after the last bullet was fired if ((blnSpace)&&(intBulletFired==intBulletRecharge)) { fireBullet(); intBulletFired=0; } // increments intBulletFired if it is below the threashold. if (intBulletFired<intBulletRecharge){intBulletFired++;} //move bullets each bullet will be moved up a certain number of pixels moveBullets(); //invaders drop bombs invadersDropBombs(); //move bombs moveBombs(); //runs through the various hit tests doHitTests(); //deletes bullets that have gone off the top of the screen loseBulletsOffScreen(); //deletes bombs that have gone off the bottom of the screen loseBombsOffScreen(); //animates the aliens if (intAniCount == intSwitch) { animateAliens(1); } if (intAniCount == intSwitch * 2) { animateAliens(2); intAniCount = 0; } intAniCount++; } //the method the draw the aliens at the start of the game private void drawAliens() { //first the embedded .png files are loaded into bitmap variables BitmapImage bitInv1a = new BitmapImage(); bitInv1a.BeginInit(); bitInv1a.UriSource = new Uri("inv1a.png", UriKind.Relative); bitInv1a.EndInit(); BitmapImage bitInv1b = new BitmapImage();

Page 14: Retro Game...Retro Game Event Driven Programming End Of Module Assignment, HND Computing and Systems Development Year 1, 2011. Chichester College. Author: Alex Hughes Develop a 2D

bitInv1b.BeginInit(); bitInv1b.UriSource = new Uri("inv1b.png", UriKind.Relative); bitInv1b.EndInit(); BitmapImage bitInv2a = new BitmapImage(); bitInv2a.BeginInit(); bitInv2a.UriSource = new Uri("inv2a.png", UriKind.Relative); bitInv2a.EndInit(); BitmapImage bitInv2b = new BitmapImage(); bitInv2b.BeginInit(); bitInv2b.UriSource = new Uri("inv2b.png", UriKind.Relative); bitInv2b.EndInit(); BitmapImage bitInv3a = new BitmapImage(); bitInv3a.BeginInit(); bitInv3a.UriSource = new Uri("inv3a.png", UriKind.Relative); bitInv3a.EndInit(); BitmapImage bitInv3b = new BitmapImage(); bitInv3b.BeginInit(); bitInv3b.UriSource = new Uri("inv3b.png", UriKind.Relative); bitInv3b.EndInit(); BitmapImage bitBullet = new BitmapImage(); bitBullet.BeginInit(); bitBullet.UriSource = new Uri("bullet.png", UriKind.Relative); bitBullet.EndInit(); //five rows of aliens for (int j = 0; j < 5; j++) { //15 aliens per row for (int i = 0; i < 15; i++) { //instanciates a new user control of the type Invader Invader thisInvader = new Invader(); //using modular division aliens are created in 3 types switch (j % 3) { case (0): thisInvader.image1.Source = bitInv1a; thisInvader.lives = 1; thisInvader.points = 100; thisInvader.flavour = 1; break; case (1): thisInvader.image1.Source = bitInv2a; thisInvader.lives = 2; thisInvader.points = 200; thisInvader.flavour = 2; break; case (2): thisInvader.image1.Source = bitInv3a; thisInvader.lives = 3; thisInvader.points = 300; thisInvader.flavour = 3; break; } //invader is added to the screen cnvSpace.Children.Add(thisInvader); //a reference to the invader is added to the typed list aliens Aliens.Add(thisInvader); //a horizontal gap of 5px between invaders (dimesnion is 30*30) plus an offset of 5px Canvas.SetLeft(thisInvader, i * 35 + 5); //vertical gap if 5px plus 40px offset Canvas.SetTop(thisInvader, j * 35 + 40); //z-index is set up so that game over will appear above the sprite Canvas.SetZIndex(thisInvader, 0); } } } //the animation routine: when called with either intStep == 1 or 2 private void animateAliens(int intStep) { foreach(Invader thisInvader in Aliens) if (intStep == 1) {

Page 15: Retro Game...Retro Game Event Driven Programming End Of Module Assignment, HND Computing and Systems Development Year 1, 2011. Chichester College. Author: Alex Hughes Develop a 2D

switch (thisInvader.flavour) { case (1): thisInvader.image1.Source = bitInv1a; break; case (2): thisInvader.image1.Source = bitInv2a; break; case (3): thisInvader.image1.Source = bitInv3a; break; } } else { switch (thisInvader.flavour) { case (1): thisInvader.image1.Source = bitInv1b; break; case (2): thisInvader.image1.Source = bitInv2b; break; case (3): thisInvader.image1.Source = bitInv3b; break; } } } //draws the spare lives private void drawSpareGunners() { //four spare gunners for (int i = 0; i < 4; i++) { //handled as a list of images Image imgThisLife = new Image(); imgThisLife.Source = bitGunner; imgThisLife.Width = 40; imgThisLife.Height = 20; //adds gunner life image to canvas and a reference is added to the lives list. cnvSpace.Children.Add(imgThisLife); Lives.Add(imgThisLife); Canvas.SetLeft(imgThisLife, i * 50 + 10); Canvas.SetTop(imgThisLife, 565); } } //The draw shields method private void drawShields() { //there are 4 shield 0 to 3 for (int intShieldNo = 0; intShieldNo < 4; intShieldNo++) { //each shield has 4 rows 0 to 3 for (int row = 0; row < 4; row++) { //each row has 11 shield elements which are user controls for (int x = 0; x < 11; x++) { //provided the element is not in the cut out area at the bottom centre of the shield, //create the shield element if (!((row>1)&&(x>2)&&(x<8))) { shieldElement thisShieldElement = new shieldElement(); Shields.Add(thisShieldElement); cnvSpace.Children.Add(thisShieldElement); //135 offset, shields at 125px interval, each element 7px width. Canvas.SetLeft(thisShieldElement, 135+intShieldNo*125+x*7); //475 offset from top of screen 10 height Canvas.SetTop(thisShieldElement, 475+row*10); } } }

Page 16: Retro Game...Retro Game Event Driven Programming End Of Module Assignment, HND Computing and Systems Development Year 1, 2011. Chichester College. Author: Alex Hughes Develop a 2D

} } //when a shield element gets hit it loses 1 of its 3 lives and gets redrawn private void reDrawShield(shieldElement thisShieldElement) { switch (thisShieldElement.intLives) { case (3): thisShieldElement.imgShield.Source = bitshielda; break; case (2): thisShieldElement.imgShield.Source = bitshieldb; break; case (1): thisShieldElement.imgShield.Source = bitshieldc; break; } } //the move aliens routine private void moveAliens() { //the first thing to do is find the GetLeft position of the leftmost and rightmost aliens. //so MaxLeft is initiallially set to zero then every time an alien is to the right of it it is reset //to that value. dblMaxLeft = 0; //similarly minleft is set to a number further right than any alien dblMinLeft = 800; //we run through all the invaders on the screen and if the aliens position is greater than maxleft, //maxleft is updated //if less than current minleft, minleft is updated foreach (Invader thisInvader in Aliens) { if (dblMaxLeft < Canvas.GetLeft(thisInvader)) { dblMaxLeft = Canvas.GetLeft(thisInvader); } if (dblMinLeft > Canvas.GetLeft(thisInvader)) { dblMinLeft = Canvas.GetLeft(thisInvader); } } //if the column is going off the screen to the right the speed is reversed and a flag //(blnMoveInvDown) is set to true so that next move the aliens are also lowered if (dblMaxLeft > 700) { dblInvMove = -dblInvSpeed; blnMoveInvDown = true; } //similarly if the column has reached the left of the screen speed is set to positive and the //blnMoveInvDown flag set to true if (dblMinLeft < 0) { dblInvMove = dblInvSpeed; blnMoveInvDown = true; } //scrolls through all the invaders on the screen foreach (UIElement thisInvader in Aliens) { //moves to the left or right appropriately Canvas.SetLeft(thisInvader, Canvas.GetLeft(thisInvader) + dblInvMove); //if at screen edge moves down if (blnMoveInvDown) { Canvas.SetTop(thisInvader, Canvas.GetTop(thisInvader) + 10); }

Page 17: Retro Game...Retro Game Event Driven Programming End Of Module Assignment, HND Computing and Systems Development Year 1, 2011. Chichester College. Author: Alex Hughes Develop a 2D

} //once all invaders are moved move down flag set back to false if it was used blnMoveInvDown = false; } //routine to move the gunner private void moveGunner() { //using dblCurrentleft as a variable the gunner's position is taken dblCurrentLeft = Canvas.GetLeft(imgGunner); // blnLeft and blnRight are switched on and off by the KeyUp and KeyDown events on the Main Window // here i am putting code in so that the gunner just stops if both left and right are pressed //simultaneously. if (blnLeft && !blnRight) { dblCurrentLeft -= dblGunnerSpeed; } if (!blnLeft && blnRight) { dblCurrentLeft += dblGunnerSpeed; } //limits the gunner to the screen dimensions if (dblCurrentLeft < 0) { dblCurrentLeft = 0; } if (dblCurrentLeft > 685) { dblCurrentLeft = 685; } //resets the position of the gunner sprite Canvas.SetLeft(imgGunner, dblCurrentLeft); } //the idea behind this is that every game tick each invader has a 1 in 1000 chance of dropping a bomb //the chances of dropping get higher for each new level. private void invadersDropBombs() { //so run through all the invaders foreach (Invader thisInvader in Aliens) { //pick a random integer between 0 and intBombRate and if it is a 1 drop the bomb if (randomObj.Next(intBombRate) == 1) { //instantiate a new bomb and add it to the canvas and add a reference to it to the list Bombs. Bomb newBomb = new Bomb(); cnvSpace.Children.Add(newBomb); Bombs.Add(newBomb); //set the position of the bomb to be that of the alien that dropped it Canvas.SetLeft(newBomb, Canvas.GetLeft(thisInvader)+15); Canvas.SetTop(newBomb, Canvas.GetTop(thisInvader)+30); } } } //here is the fire bullet method private void fireBullet() { //instantiate a new bullet user control Bullet newBullet = new Bullet(); //put it on the screen and add reference to the bullets list cnvSpace.Children.Add(newBullet); Bullets.Add(newBullet); //set its position to that of the centre of the gunner Canvas.SetLeft(newBullet, Canvas.GetLeft(imgGunner) + imgGunner.ActualWidth*.5); Canvas.SetTop(newBullet, Canvas.GetTop(imgGunner)); } //here is the move bullets method private void moveBullets() { //runs through all the bullets currently on the screen and moves them 1 by 1 foreach (Bullet thisBullet in Bullets) { //the bullet user control actually has a method to move it defined within the control thisBullet.MoveBullet(intBulletSpeed); }

Page 18: Retro Game...Retro Game Event Driven Programming End Of Module Assignment, HND Computing and Systems Development Year 1, 2011. Chichester College. Author: Alex Hughes Develop a 2D

} //here is the move bombs method private void moveBombs() { //runs through the list of bombs actively on the screen and calls the MoveBomb method in the user control foreach (Bomb thisBomb in Bombs) { thisBomb.MoveBomb(intBombSpeed); } } //this is the list all all the hit tests that must be performed and what to do about them it is run every game tick. private void doHitTests() { //First bullets hitting invaders ///////////////////////////////////// //runs through all bullets and for each one sees if it has hit an invader foreach(Bullet thisBullet in Bullets) { foreach(Invader thisInvader in Aliens) { if (BulletInvaderHitTest(thisBullet,thisInvader)) // if the invader has been hit it loses a life and its opacity fades. // if it is out of lives it is added // to the dead aliens list and you get points for it { thisInvader.lives --; thisInvader.Opacity -= .2; if (thisInvader.lives==0) { DeadAliens.Add(thisInvader); intScore+= thisInvader.points; lblScore.Content = "Score : " + intScore.ToString(); } //the bullet is added to dead bullets if it has hit anything DeadBullets.Add(thisBullet); } } } //the dead bullets are then removed from the list and from the screen //this method is neccessary because the contents of the typed list cannot be altered whilst a //foreach loop is running on it. foreach (Bullet thisBullet in DeadBullets) { Bullets.Remove(thisBullet); cnvSpace.Children.Remove(thisBullet); } //the dead bullets list is then cleared to avoid deleting them twice. DeadBullets.Clear(); //the same routine is run for the aliens with the addition that if all the aliens are killed the //winLevel mothod is called foreach (Invader thisInvader in DeadAliens) { Aliens.Remove(thisInvader); cnvSpace.Children.Remove(thisInvader); } DeadAliens.Clear(); if (Aliens.Count() == 0) { winLevel(); }

Page 19: Retro Game...Retro Game Event Driven Programming End Of Module Assignment, HND Computing and Systems Development Year 1, 2011. Chichester College. Author: Alex Hughes Develop a 2D

//The next hit test is for bombs hitting the gunner //////////////////////////////////////////////////// foreach (Bomb thisBomb in Bombs) { if (BombGunnerHitTest(thisBomb)) { loseLife(); DeadBombs.Add(thisBomb); } } foreach(Bomb thisBomb in DeadBombs) { Bombs.Remove(thisBomb); cnvSpace.Children.Remove(thisBomb); } DeadBombs.Clear(); //The next hittest is for bombs hitting the shields /////////////////////////////////////////////////// //runs through all bombs on screen foreach (Bomb thisBomb in Bombs) //as there are rather a lot of shield elements it only runs if the bomb is in the vicinity if (Canvas.GetTop(thisBomb) > 450) { { //runs through each shield element foreach (shieldElement thisShieldElement in Shields) { //if the element is hit it loses a life if (BombShieldElementHitTest(thisBomb, thisShieldElement)) { thisShieldElement.intLives--; //and the bomb is added to the dead bombs list to be deleted later DeadBombs.Add(thisBomb); // if the shield element is dead it is removed else it is redrawn with a new //graphic if (thisShieldElement.intLives == 0) { DeadShieldElements.Add(thisShieldElement); } else { reDrawShield(thisShieldElement); } } } } } //as before the dead bombs and dead shield elements are removed. One slight problem is that a bomb //can kill more than 1 shield element at a time. foreach (Bomb thisBomb in DeadBombs) { Bombs.Remove(thisBomb); cnvSpace.Children.Remove(thisBomb); } DeadBombs.Clear(); foreach (shieldElement thisShieldElement in DeadShieldElements) { Shields.Remove(thisShieldElement); cnvSpace.Children.Remove(thisShieldElement); } DeadShieldElements.Clear(); //the next hit test is for bullets hitting shield elements to make a pillar-box ////////////////////////////////////////////////////////////////////////////////

Page 20: Retro Game...Retro Game Event Driven Programming End Of Module Assignment, HND Computing and Systems Development Year 1, 2011. Chichester College. Author: Alex Hughes Develop a 2D

foreach (Bullet thisBullet in Bullets) { foreach (shieldElement thisShieldElement in Shields) { // if it hits the shield element loses a life and the bullet gets added to the deadbullets list if (BulletShieldElementHitTest(thisBullet,thisShieldElement)) { thisShieldElement.intLives--; DeadBullets.Add(thisBullet); //if the shield element is dead it is removed or else it is redrawn with damage. if (thisShieldElement.intLives == 0) { DeadShieldElements.Add(thisShieldElement); } else { reDrawShield(thisShieldElement); } } } } // dead bullets and shield elements are deleted from screen and active lists as before foreach (Bullet thisBullet in DeadBullets) { Bullets.Remove(thisBullet); cnvSpace.Children.Remove(thisBullet); } DeadBullets.Clear(); foreach (shieldElement thisShieldElement in DeadShieldElements) { Shields.Remove(thisShieldElement); cnvSpace.Children.Remove(thisShieldElement); } DeadShieldElements.Clear(); } //Now here are the actual hit tests //Bullets hit invaders private bool BulletInvaderHitTest(Bullet thisBullet, Invader thisInvader) { //two rectangles are defined: one around the bullet, one around the invader Rect recBullet = new Rect(Canvas.GetLeft(thisBullet), Canvas.GetTop(thisBullet), thisBullet.ActualWidth, thisBullet.ActualHeight); Rect recInvader = new Rect(Canvas.GetLeft(thisInvader), Canvas.GetTop(thisInvader), thisInvader.ActualWidth, thisInvader.ActualHeight); //The intersectsWith method is called on recBullet with the argument recInvader which returns true if the rectangles overlap. //This result is returned to the condition statement calling the method and it is similar to a function in visual basic. return recBullet.IntersectsWith(recInvader); } //Bombs hit Gunners private bool BombGunnerHitTest(Bomb thisBomb) { Rect recBomb = new Rect(Canvas.GetLeft(thisBomb), Canvas.GetTop(thisBomb), thisBomb.ActualWidth, thisBomb.ActualHeight); Rect recGunner = new Rect(Canvas.GetLeft(imgGunner), Canvas.GetTop(imgGunner), imgGunner.ActualWidth, imgGunner.ActualHeight); return recBomb.IntersectsWith(recGunner); } //Bombs Hit shield elements

Page 21: Retro Game...Retro Game Event Driven Programming End Of Module Assignment, HND Computing and Systems Development Year 1, 2011. Chichester College. Author: Alex Hughes Develop a 2D

private bool BombShieldElementHitTest(Bomb thisBomb, shieldElement thisShieldElement) { Rect recBomb = new Rect(Canvas.GetLeft(thisBomb), Canvas.GetTop(thisBomb), thisBomb.ActualWidth, thisBomb.ActualHeight); Rect recShieldElement = new Rect(Canvas.GetLeft(thisShieldElement), Canvas.GetTop(thisShieldElement), 10, 20); return recBomb.IntersectsWith(recShieldElement); } //bullets hit shield elements private bool BulletShieldElementHitTest(Bullet thisBullet, shieldElement thisShieldElement) { Rect recBullet = new Rect(Canvas.GetLeft(thisBullet), Canvas.GetTop(thisBullet), thisBullet.ActualWidth, thisBullet.ActualHeight); Rect recShieldElement = new Rect(Canvas.GetLeft(thisShieldElement), Canvas.GetTop(thisShieldElement), 10, 20); return recBullet.IntersectsWith(recShieldElement); } //in this method all bullets that have flown off the top of the screen are deleted. private void loseBulletsOffScreen() { foreach(Bullet thisBullet in Bullets) if (Canvas.GetTop(thisBullet) < 0) { DeadBullets.Add(thisBullet); } foreach (Bullet thisBullet in DeadBullets) { Bullets.Remove(thisBullet); cnvSpace.Children.Remove(thisBullet); } DeadBullets.Clear(); } private void loseBombsOffScreen() { foreach(Bomb thisBomb in Bombs) { if (Canvas.GetTop(thisBomb) >543) { DeadBombs.Add(thisBomb); } } foreach(Bomb thisBomb in DeadBombs) { Bombs.Remove(thisBomb); cnvSpace.Children.Remove(thisBomb); } DeadBombs.Clear(); } private void Window_KeyDown(object sender, KeyEventArgs e) { if (e.Key == Key.Space) { blnSpace = true; if (blnGameStarted == false) { startGame(); blnGameStarted = true; } }

Page 22: Retro Game...Retro Game Event Driven Programming End Of Module Assignment, HND Computing and Systems Development Year 1, 2011. Chichester College. Author: Alex Hughes Develop a 2D

if (e.Key == Key.Left) { blnLeft = true; } if (e.Key == Key.Right) { blnRight = true; } if (e.Key == Key.Q) { stopGame(); } } private void Window_KeyUp(object sender, KeyEventArgs e) { if (e.Key == Key.Space) { blnSpace = false; } if (e.Key == Key.Left) { blnLeft = false; } if (e.Key == Key.Right) { blnRight = false; } } private void loseLife() { intLives --; if (intLives == 0) { gameOver(); } else { Image thisLife = Lives.Last(); Lives.Remove(thisLife); cnvSpace.Children.Remove(thisLife); } if (intLives==0) {gameOver();} } private void gameOver() { if (intScore > intHighScore) { intHighScore = intScore; lblHighScore.Content = "High Score : " + intHighScore.ToString(); } lblGameOver.Visibility=Visibility.Visible; lblPressSpace.Visibility=Visibility.Visible; blnGameStarted=false; stopGame(); } private void winLevel() { myTimer.Stop(); lblLevelCompleted.Visibility = Visibility.Visible; intBonus = intLevel * 1000;

Page 23: Retro Game...Retro Game Event Driven Programming End Of Module Assignment, HND Computing and Systems Development Year 1, 2011. Chichester College. Author: Alex Hughes Develop a 2D

lblLevelCompleted.Content = ("Level "+intLevel.ToString()+" completed!!! Bonus "+intBonus.ToString()+ "!!!"); Thread.Sleep(2000); lblLevelCompleted.Visibility = Visibility.Hidden; intScore += intBonus; lblScore.Content = "Score : " + intScore.ToString(); intLevel++; lblLevel.Content = "Level : " + intLevel.ToString(); dblInvSpeed += dblInvSpeed * .1; intBombRate -= (intBombRate/10); drawAliens(); foreach (shieldElement thisShieldElement in Shields) { cnvSpace.Children.Remove(thisShieldElement); } Shields.Clear(); drawShields(); myTimer.Start(); } private void help_Click(object sender, RoutedEventArgs e) { help h = new help(); h.ShowDialog(); } private void about_Click(object sender, RoutedEventArgs e) { about a = new about(); a.ShowDialog(); } } }

Page 24: Retro Game...Retro Game Event Driven Programming End Of Module Assignment, HND Computing and Systems Development Year 1, 2011. Chichester College. Author: Alex Hughes Develop a 2D

Testing

Test Grid No. Date Test Expected Result Actual Result Comments

1 28.10.2011 Aliens move in formation

Reach right of screen turn then go down and left

As expected Aliens move ok.

2 28.10.2011 Bullets kill aliens Bullet kills alien when it hits

Not always killing aliens when they go through.

Bullet was flying right over the alien. decreased the bullet speed and the timer interval.

3 28.10.2011 Bullets kill aliens Bullet kills alien when it hits

Ok.

4 28.10.2011 Shields Degrade when hit by bombs

Shield should degrade when hit

Sometime bullets are passing through

It may have been a problem with using the actual width property for the shield element. I have replaced it with the pixel value . Now sometime bombs degrade2 elements at a time.

5 28.10.2011 Ships die when hit Life lost using lives -- Yup 5 hits and you are gone

I want to put spare ships at the bottom of the screen to illustrate the lives.

6 3.11.2011 Spare Ships disappear when lives ost

Spare ship disappears Found a bug. The lives integer is updated but the spares are not and an exception occurs trying to delete an image that does not exist.

Fixed the bug. All ships deleted and new ones drawn for each new game

7 3.11.2011 New Level Functionality

New shields and new aliens for next level

Shields do not renew. This could get tricky as we progress up the levels

Shields all deleted and redrawn at level start

8 3.11.2011 New Level Functionality

Levels 4 and 5 load ok ok Because each level 10% is deducted from intBombRate I was worried that at some time it would not be an integer. it starts at 1000 for L1 so L2 900 L3 810 L4 729 L5 656.1?

9 5.11.2011 Bullets kill aliens the right number of times

Functionality has been added to give aliens multiple lives and I was wondering if they got killed the right way.

Found a bug. The bullets only die if they have actually annihilated an alien. Not if they have just taken 1 of its lives.

Fixed the bug. It’s going to make the game harder to play at higher levels because the aliens are harder to kill. I have reduced the bullet refresh so you get more bullets. Am

Page 25: Retro Game...Retro Game Event Driven Programming End Of Module Assignment, HND Computing and Systems Development Year 1, 2011. Chichester College. Author: Alex Hughes Develop a 2D

considering doing a flying saucer feature that gioves you extra powers like double bulets from either side of the ship or nukes etc.

10 8.11.2011 Help and About functionality

Help and About load and display.

Help and about not picking up from embedded XHTML files.

After some research I have used files not embedded but included in the release folder. it is possible to edit these in the project and have them copies to the output directory.

11 8.11.2011 More Help and About Help and about display graphics and links

Alien images not present in help as accessed from output directory. Link to my page in about trioes to open in Window – not new browser.

Ok this was a nightmare. set up 2 invader graphics as content and had them copied to output directory but then they did not appear on the screen and the aliens animated badly. When I reset them they still did not appear and I had to restart VS2010 so this may be a bug in VS2010. P{roblem eventually resolved by making extra copies of them. Fixed, link.

12 9.11.2011 Download to game works

Game is uploaded to my site as a zip. It is no longer a single .exe file which I regret but the zipped folder contains help and mainfest

Icon does not appear unless folder is unzipped but Maxthon unzips it to a folder that can be accessed and when run the help and about come up ok.

No problem. Should try other browsers. Also typo in About.

13 9.11.2011 Sourcecode link Follow the link from “About” to download the whole VS2010 project

6MB zip file was too big to host on 000webhost.com. Will consider moving my site. Placed it in my Hotmail.com skydrive and posted link on the site. A bit annoying to have to follow 2 links.

There is definitely going to be a rerelease of this version with improved help (game should stop whilst help being viewed)

14 10.11.2011 Last play through of download

Game works ok Space invaders can come down below shields withoput a gameover being called.

Oops. never fixed this bug. Will have to go into the bext release.

Page 26: Retro Game...Retro Game Event Driven Programming End Of Module Assignment, HND Computing and Systems Development Year 1, 2011. Chichester College. Author: Alex Hughes Develop a 2D

Feedback Form : Space Invaders 2 Questionaire

Name Adam Swatton

Do you describe yourself as a gamer? (y/n) Yes

What did you think of the game?

The game itself is a good approximation of a classic game and is represented very well. The controls are responsive and the game looks as it should for the intended purpose. It does have a good level of playability and increases in difficulty the further you progress. Good game, and would play it again!

Were able to find the controls easily?(y/n) Yes, standardised keyboard input.

What level did you get to ? 3

How playable do you think the game is? (0-5) 0=Superman 64 5=Tomb Raider.

4

How did you feel about the number of invaders? (too many/ too few/ about right)

About right

How did you feel about the number of bombs? The rate of fire was good and the number of bombs appeared to increase whenever you enhance in levels.

How easy was it to download and install? Very

Which improvements would you like to see? Additional bonuses and functions (weapons/shields). Message of some description for the loss of a life or progression through levels.

Name Val hughes

Do you describe yourself as a gamer? (y/n) No first timer!

What did you think of the game?

It was exciting to a first timer but I think my score 6900 was accidental!

Were able to find the controls easily?(y/n) yes

What level did you get to ? Level 1?

How playable do you think the game is? (0-5) 0=Superman 64 5=Tomb Raider.

1?

How did you feel about the number of invaders? (too many/ too few/ about right)

Too many

How did you feel about the number of bombs? Bit difficult to control

How easy was it to download and install? Ok with some guidance website didn’t seem to have an easy to find link

Which improvements would you like to see? Easier access to website link (but this may be due to total lack of experience) I would need instructions on what to do eg didn’t know what were bombs or how to stop things falling out of sky Nice colours though and after a while I felt more confident about zapping the little creatures! But success rate was almost certainly pure accident---

Don Fowdrey

Page 27: Retro Game...Retro Game Event Driven Programming End Of Module Assignment, HND Computing and Systems Development Year 1, 2011. Chichester College. Author: Alex Hughes Develop a 2D

To alexis hughes

Sorry, Alex, it doesn't want to run on my machine. It says I have to install a .NET framework something, and I don't know how.

Don

Questionaire

Name Poli Fowdrey

Do you describe yourself as a gamer? (y/n) Definitely not!

What did you think of the game?

It looks really good. Authentic styling and fun to play. However, I managed to break it. Twice. The first time it crashed and there was no help or instructions to fix it. I started again and the second time the line of aliens just kept coming and didn’t disappear when they reached the planet, as they do in the original game. I killed all but one, but it kept going down and I couldn’t move on. I suspect my ‘don’t move very much and keep on firing strategy’ was to blame, but I am good at breaking games.

Were able to find the controls easily?(y/n) Yes, no problem. It was very straightforward

What level did you get to ? Didn’t get past level one second time, but I was on level two first time round when it crashed

How playable do you think the game is? (0-5) 0=Superman 64 5=Tomb Raider.

Never played either of those games, but this was about a 9 for playability. It would have been a 10 but for the bugs

How did you feel about the number of invaders? (too many/ too few/ about right)

Just about right, but it would be good if there were more and faster in higher levels (perhaps there are; I’ll never know now!)

How did you feel about the number of bombs? There were a lot of them, but they didn’t do much damage

How easy was it to download and install? Wouldn’t work on my Mac, but quite straightforward on a PC

Which improvements would you like to see? Fix the bugs so it is Poli-proof. Make it work on a Mac. Add some groovy noises and you’re there! =)

Name Pete Mackean Do you describe yourself as a gamer? (y/n) No, not a series one, just dabble What did you think of the game? Wow, you have achieved a very amazing

playable game. The retro look works so well and the simple animated graphics are very clean, shame you have no sounds yet. A little clash of colours but easily rectified, the way you have to kill the invaders is clever having to hit them more than once, the hail of invader bullets is brilliant, and the towers definitely add

Page 28: Retro Game...Retro Game Event Driven Programming End Of Module Assignment, HND Computing and Systems Development Year 1, 2011. Chichester College. Author: Alex Hughes Develop a 2D

the real game feel, scoring and extra levels is very nice to see. But what happens if the invaders actually pass the gun going off the bottom of screen, there is no game end Truly addictive, Alex it’s a WINNER, you’re hired!

Were able to find the controls easily?(y/n) Yes, I didn’t really need the help menu, and nice help it is

What level did you get to? Level 3 first time and still playing, it’s brilliant and so like the real thing, well done

How playable do you think the game is? (0-5) 0=Superman 64 5=Tomb Raider.

Very playable, the retro look is very good

How did you feel about the number of invaders? (too many/ too few/ about right)

Just as the original version, the right number for me, it gives the game an edge as the invaders close in with a chance to invade

How did you feel about the number of bombs? Again nothing wrong with the amount, it’s very clever, although the red colour means they do get lost in the background, maybe adds a bit more fun, perhaps white next time

How easy was it to download and install? Very simple, although your executable hasn’t got an icon, you have one for the program

Which improvements would you like to see? Icon on executable Maybe white bullets or an outline may help, the same with the red base gunner, gets a bit lost with the background I know you spoke of doing the bonus saucer flying across the top And definitely you must get the sounds working or are you just teasing us all Instruction could do with being stronger/larger Could do with a pause button, resume game, and new game when game ends, maybe a file menu

Reflection on User survey. The game is ok. To keep people wanting to play it needs to be less monotonous. It needs to have extra functionality. As a

minimum a saucer that gives a lives bonus or new shields or improved guns or a nuke that kills all aliens within a near

radius. Adam Swatton commented on no feedback between levels. I actually created feedback of a Level 1 completed label

and this was displayed by making it visible, using the Thread.Sleep(2000) command and then making it invisible again .

It paused but didn’t show the message. I don’t know why this hasn’t worked. Maybe it’s a racing error. I wanted to do a

mothership that moved at random speed to a random screen location and when it got there went somewhere else and

dropped a lot of bombs and needed 50 hits. This, I think would round the level off nicely. Also I think the rank formation is a

bit too strict. Some invaders should break rank and attack. This could be pretty easy to do. Write a function for curved flight.

Some kind of quadratic would probably do the trick

There is no functionality for invaders getting to the bottom of the screen. It needs a game over function.

Page 29: Retro Game...Retro Game Event Driven Programming End Of Module Assignment, HND Computing and Systems Development Year 1, 2011. Chichester College. Author: Alex Hughes Develop a 2D

Downloading had mixed results. Normally when a machine downloads an .exe file there are many warnings about running it

and I think putting links to it in an email may cause trouble with spam filters. The WPF .exe will not run on every computer

as it would have done in pure c#. One solution to this is to compile to Silverlight which is a relatively common format. It is

easier to download than .NET framework and runs as a browser plugin so there would be no security messages.

I investigated the crash in Poli Fowdrey’s test doing a debug on the compiled exe file.

The exception comes when you play a second game running on from the first and lose a life.

This gives less information than a debug in VS2010 as you do not have the whole project folder to work with. It does

reference lines in the code though. Unfortunately variable names are lost by the compiler but function names are kept. The

exception was as follows:

System.InvalidOperationException was unhandled

Message=Sequence contains no elements

Source=System.Core

StackTrace:

at System.Linq.Enumerable.Last[TSource](IEnumerable`1 source)

at SpaceInvaders2.MainWindow.loseLife() in C:\Users\Alex\Documents\Visual Studio

2010\Projects\SpaceInvaders2\SpaceInvaders2\MainWindow.xaml.cs:line 843

at SpaceInvaders2.MainWindow.doHitTests() in C:\Users\Alex\Documents\Visual Studio

2010\Projects\SpaceInvaders2\SpaceInvaders2\MainWindow.xaml.cs:line 608

at SpaceInvaders2.MainWindow.gameLoop() in C:\Users\Alex\Documents\Visual Studio

2010\Projects\SpaceInvaders2\SpaceInvaders2\MainWindow.xaml.cs:line 245

at SpaceInvaders2.MainWindow.myTimer_Elaspsed(Object source, EventArgs e) in

C:\Users\Alex\Documents\Visual Studio 2010\Projects\SpaceInvaders2\SpaceInvaders2\MainWindow.xaml.cs:line

184

at System.Windows.Threading.DispatcherTimer.FireTick(Object unused)

at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Int32

numArgs)

at MS.Internal.Threading.ExceptionFilterHelper.TryCatchWhen(Object source, Delegate method, Object

args, Int32 numArgs, Delegate catchHandler)

at System.Windows.Threading.DispatcherOperation.InvokeImpl()

at System.Windows.Threading.DispatcherOperation.InvokeInSecurityContext(Object state)

at System.Threading.ExecutionContext.runTryCode(Object userData)

at System.Runtime.CompilerServices.RuntimeHelpers.ExecuteCodeWithGuaranteedCleanup(TryCode code,

CleanupCode backoutCode, Object userData)

at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback

callback, Object state)

at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback

callback, Object state, Boolean ignoreSyncCtx)

Page 30: Retro Game...Retro Game Event Driven Programming End Of Module Assignment, HND Computing and Systems Development Year 1, 2011. Chichester College. Author: Alex Hughes Develop a 2D

at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback

callback, Object state)

at System.Windows.Threading.DispatcherOperation.Invoke()

at System.Windows.Threading.Dispatcher.ProcessQueue()

at System.Windows.Threading.Dispatcher.WndProcHook(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr

lParam, Boolean& handled)

at MS.Win32.HwndWrapper.WndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean&

handled)

at MS.Win32.HwndSubclass.DispatcherCallbackOperation(Object o)

at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Int32

numArgs)

at MS.Internal.Threading.ExceptionFilterHelper.TryCatchWhen(Object source, Delegate method, Object

args, Int32 numArgs, Delegate catchHandler)

at System.Windows.Threading.Dispatcher.InvokeImpl(DispatcherPriority priority, TimeSpan timeout,

Delegate method, Object args, Int32 numArgs)

at MS.Win32.HwndSubclass.SubclassWndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam)

at MS.Win32.UnsafeNativeMethods.DispatchMessage(MSG& msg)

at System.Windows.Threading.Dispatcher.PushFrameImpl(DispatcherFrame frame)

at System.Windows.Threading.Dispatcher.PushFrame(DispatcherFrame frame)

at System.Windows.Application.RunDispatcher(Object ignore)

at System.Windows.Application.RunInternal(Window window)

at System.Windows.Application.Run(Window window)

at SpaceInvaders2.App.Main() in C:\Users\Alex\Documents\Visual Studio

2010\Projects\SpaceInvaders2\SpaceInvaders2\obj\x86\Release\App.g.cs:line 0

InnerException:

This sequence contains no elements error is on one of the typed lists. It uses the Last function and was called by LoseLife().

So I think I have forgotten to reset the lives at the bottom of the screen when the game starts again. This is the only list

where the last element is called.

The error actually occurs when you lose the second game. It is possible that we are going into negative lives with intLives

hence it never reaches zero.

I fixed the intlives error and put a simple if statement so that if the aliens get as far as the shields gameOver() is called.

That is about all I have time for before the deadline. But I hope to keep working on the project to make something I could

release in Silverlight possibly adding mobile device capability for windows phones and yes! Apple Mac compatibility.

Page 31: Retro Game...Retro Game Event Driven Programming End Of Module Assignment, HND Computing and Systems Development Year 1, 2011. Chichester College. Author: Alex Hughes Develop a 2D

Critical Reflection I came into this unit worried that we weren’t getting enough done with the PaintCalc but writing this game from the ground

up has really inspired me. We began by just getting the basic functionality of a bullet hitting an invader in the WPF graphics

format which is different to the Visual Basic graphics engine. David Olliff, the instructor gave me just enough information to

add complexity in the form of dynamically created images, user controls and typed lists which had been introduced in the

last assignment and with a few simple blocks I built this game. Considering I had virtually no experience of c# at the start of

the unit I feel I have come a long way and I am now addicted to VS2010 (I need to get some time in with CodeBlocks to even

this out!)

I have taken a book out of the library on WPF and just a quick glace into the 3d section shows that it is a really simple API to

use. You just put coordinates as an ascii list into the xaml along with camera position and it shades your object complete

with Phong normal-interpolation and specular and ambient lighting models. It even renders a skin image onto the model.

When I wrote a simple flat shader in Visual Basic I enjoyed working out vector products to get angles and line interpolations

through a pin-hole camera but the code was so unintelligible I couldn’t show it to anybody even though I was using arrays

to make 3d coordinates easier to handle with for loops. With Object Orientated C# you can make data structures like

vectors and define methods for adding multiplying and interpolating them and with the WPF graphics engine you can

render the resulting polygons easily but you don’t need to because a complete 3d engine (optimized for GPU) is available to

you.

I have definitely got the bug for games programming and really want to rewrite “Elite” which has a 3d vector graphic

spaceship flying through a universe of stars to do trading missions. I would also like to create 3d noughts and crosses with a

mouse controlled viewport.

I am working in my spare time on 3d Studio Max skills (incredibly complex program) and I would like to make a proper 3d

game similar to Virtua Fighter (but with only 3 attacks and 3 defences (high middle and low)) and am hoping to get

inspiration from freeze-framing Bruce Lee Films for the moves and using stock 3d characters. I am busy - so this may be a

project for the next holiday. I could certainly use some pointers in Max and cannot yet see how you would export multiple

.obj files into c# data structures to animate into the moves.

All in all I am really keen on the C# language and cannot wait to learn properly about classes, methods, properties and

polymorphism when the next programming unit starts.

In the meantime I will still be working on my c# console internet PHP noughts and crosses and trying to get Mike Eason to

do something similar with his RPG game – probably using xml as c# has an xml parser built in.

When I was studying A-Level Maths we did a lot of calculus on finding volumes of rotation or centre of gravity or moments

of inertia on mathematical shapes. Now with computers as powerful as they are I am really looking forward to using those

principals on irregular shapes defined in polygons (or voxels) to create physics simulations of Newtonian mechanics. There

is a program made by UCSF called Amber which uses physics and Quantum chemistry models to predict how proteins and

enzymes would react and it is my goal to work on this or a similar project a few years down the line.