SpaceEvaders

by Neil: Y8 Age ~13

Introduction

SpaceEvaders is an interesting contribution from Neil, a young beginner. Use the arrow keys to avoid the enemies that move from left to right (H), vertically down (V) and up from the bottom (B). When a horizontally moving enemy reaches the right extremity it appears next at the far left, with a random Y co-ordinate. The vertical enemies behave in an analogous fashion. There is code to prevent enemies from moving in single file (which would make them easier to evade). There are seven enemies to watch out for so it can be difficult to avoid them all. An apparent collision between a horizontal and vertical enemy leaves both unscathed.

The new positions are checked for collisions before the characters are printed to the screen. This means that you can be shown your impending fate with an enemy touching you before you are told your final score. You never see yourself being wiped out! The following screenshot shows a game in progress.

Game in progress

Game in progress

After each loss, you have the chance of another life. Your score returns to zero and you start in the same place each time but the enemies retain their positions from your previous life. We like the option to play again at a touch of the space bar (particularly after an enemy has been too lucky). This is an example of the end of a game:

Game over

Game over

Neil's commented code is easy to follow, but there are several very similar sections. We expect that as he progresses he will make use of procedures with parameters and arrays to make his code shorter and easier to maintain. The program uses the Crt unit so it is simpler to try it in Lazarus than in Delphi.

The Code

program SpaceEvaders;
{
    Copyright (c) 2012 Neil

    Licensed under the Apache License, Version 2.0 (the "License"); you may not
    use this file except in compliance with the License, as described at
    http://www.apache.org/licenses/ and http://www.pp4s.co.uk/licenses/ }

uses
  Crt, SysUtils;

const
  //co-ords for current score
  scoretextX = 1;
  scoretextY = 1;
  //co-ords for final score
  centreX = 35;
  centreY = 12;
  centre2Y = 14;
  centre2X = 30;
  centre3X = 30;
  centre3Y = 16;
  centre4Y = 18;
  centre4X = 27;
  PowerLevel = 8999;
var
  c : char;
  bVenemy2X, bVenemy2Y, bVenemyX, bVenemyY, Venemy3X, Venemy3Y,
    score, Venemy2X, Venemy2Y, playerX, playerY, HenemyX, HenemyY, Henemy2X,
    Henemy2Y, VenemyX, VenemyY, repeatender : integer;

procedure endsgame;
  begin
    repeatender := 1;
    sleep(1000);
    //on touching the enemy the game pauses slightly so you can see your predicament
    clrscr;
    gotoxy(centreX, centreY);
    writeln('YOU LOSE');
    sleep(400);
    gotoxy(centre2X, centre2Y);
    Write('Your score was: ');
    Write(score);
    sleep(400);
    gotoxy(centre3X, centre3Y);
    writeln ('Press esc to finish');
    gotoxy(centre4X, centre4Y);
    writeln ('Press space to play again');
    repeat
      if (keypressed = True) then
        begin
          c := readkey;
          case c of
            #27 : halt; //escape
            #32 : begin
                    score := 0;
                    repeatender := repeatender + 1;
                    playerX := 11;
                    playerY := 10;
                 end;
          end;
        end;
    until repeatender = 2;
end;

begin
  playerX := 11; //assigns the player
  playerY := 10;
  HenemyX := 1;  //horizontal enemy
  HenemyY := 12;
  Henemy2X := 5; //second horizontal enemy
  Henemy2Y := 20;
  VenemyY := 1;  //vertical enemy
  VenemyX := 18;
  Venemy2X := 6; //second vertical enemy
  Venemy2Y := 1;
  score := 0;    //score
  Venemy3X := 12;
  Venemy3Y := 1;
  bVenemyY := 1;
  bVenemyX := 5;
  bVenemy2Y := 1;
  bVenemy2X := 13;

  textbackground(blue); //makes the background blue
  textcolor(yellow);    //makes the text yellow
  cursoroff;            //turns off the cursor
  Randomize;

  repeat
    if (keypressed = True) then
      begin
        c := readkey;
        case c of
          #75 : Dec(playerX); //left
          #77 : Inc(playerX); //right
          #72 : Dec(playerY); //up
          #80 : Inc(playerY); //down
          #27 : halt;         //escape
        end;
      end;

    clrscr;
    gotoxy(playerX, playerY);
    Write('X');  //writes X (the player) at co-ord playerX, playerY

    if playerX < 1 then
      playerX := 80;
    if playerX > 80 then
      playerX := 1;
    if playerY < 1 then
      playerY := 25;
    if playerY > 25 then
      playerY := 1;

    gotoxy(HenemyX, HenemyY);
    Write('H');              //H for Henemy
    HenemyX := HenemyX + 1;  //this makes it move from left to right

    if HenemyX < 1 then
      HenemyX := 80;
    if HenemyY < 1 then
      HenemyY := 25;
    if HenemyX > 80 then
      begin //puts the Henemy on a random Y coordinate
            //once it has reached the end of the window
        HenemyX := 1;
        HenemyY := random(25) + 1;
      end;
    if HenemyY >= 25 then
      HenemyY := 1;
    if HenemyY = Henemy2Y then
      begin
        HenemyX := 1;
        HenemyY := random(25) + 1;
      end;

    if (HenemyX = playerX) and (HenemyY = playerY) then
      endsgame;   //end of Henemy code

    gotoxy(Henemy2X, Henemy2Y); //second Henemy stuff
    Write('H');
    Henemy2X := Henemy2X + 1;

    if Henemy2X < 1 then
      Henemy2X := 80;
    if Henemy2Y < 1 then
      Henemy2Y := 25;
    if Henemy2X > 80 then
      begin
        Henemy2X := 1;
        Henemy2Y := random(25) + 1;
      end;
    if Henemy2Y >= 25 then
      Henemy2Y := 1;
    if Henemy2Y = HenemyY then
      begin
        Henemy2X := 1;
        Henemy2Y := random(25) + 1;
      end;

    if (Henemy2X = playerX) and (Henemy2Y = playerY) then
      endsgame; //end of second Henemy stuff (it's exactly the same as the first one)

    gotoxy(VenemyX, VenemyY); //makes the Venemy - like the Henemy but vertically moving downwards
    Write('V');
    VenemyY := VenemyY + 1;

    if VenemyY >= 26 then
      begin
        VenemyY := 1;
        VenemyX := random(80) + 1;
      end;
    if VenemyX >= 80 then
      VenemyX := 1;

    if (VenemyX = playerX) and (VenemyY = playerY) then
      endsgame; //end of Venemy code

    gotoxy(Venemy2X, Venemy2Y);  //second Venemy (like the first one)
    Write('V');
    Venemy2Y := Venemy2Y + 1;

    if Venemy2Y >= 26 then
      begin
        Venemy2Y := 1;
        Venemy2X := random(80) + 1;
      end;
    if Venemy2X >= 80 then
       Venemy2X := 1;

    if (Venemy2X = playerX) and (Venemy2Y = playerY) then
      endsgame; //end of second Venemy code

    gotoxy(Venemy3X, Venemy3Y);  //third Venemy (like the second one)
    Write('V');
    Venemy3Y := Venemy3Y + 1;

    if Venemy3Y >= 26 then
      begin
        Venemy3Y := 1;
        Venemy3X := random(80) + 1;
      end;
    if Venemy3X >= 80 then
      Venemy3X := 1;

    if (Venemy3X = playerX) and (Venemy3Y = playerY) then
      endsgame; //end of third Venemy code

    gotoxy(bVenemyX, bVenemyY); //a Venemy that comes from the bottom 8)
    Write('B');
    bVenemyY := bVenemyY - 1;

    if bVenemyY <= 0 then
      begin
        bVenemyY := 25;
        bVenemyX := random(80) + 1;
      end;
    if bVenemyX >= 80 then
      bVenemyX := 1;
    if bVenemyX = VenemyX then
      begin
        VenemyY := 1;
        VenemyX := random(80) + 1;
      end;
    if bVenemyX = Venemy2X then
      begin
        Venemy2Y := 1;
        Venemy2X := random(80) + 1;
      end;
    if bVenemyX = Venemy3X then
      begin
        Venemy3Y := 1;
        Venemy3X := random(80) + 1;
      end;

    if (bVenemyX = playerX)  and (bVenemyY = playerY) then
       endsgame; //end of bVenemy code

    gotoxy(bVenemy2X, bVenemy2Y); //a second Venemy that comes from the bottom 8)
    Write('B');
    bVenemy2Y := bVenemy2Y - 1;

    if bVenemy2Y <= 0 then
      begin
        bVenemy2Y := 25;
        bVenemy2X := random(80) + 1;
      end;
    if bVenemy2X >= 80 then
      bVenemy2X := 1;
    if bVenemy2X = VenemyX then
      begin
        VenemyY := 1;
        VenemyX := random(80) + 1;
      end;
    if bVenemy2X = Venemy2X then
      begin
        Venemy2Y := 1;
        Venemy2X := random(80) + 1;
      end;
    if bVenemy2X = Venemy3X then
      begin
        Venemy3Y := 1;
        Venemy3X := random(80) + 1;
      end;

    if (bVenemy2X = playerX) and (bVenemy2Y = playerY) then
      endsgame; //end of 2nd bVenemy code

    gotoxy(scoretextX, scoretextY); //for writing out the score
    Write('Score: ', score);
    score := score + 1;
    sleep(25);
  until PowerLevel > 9000; // WHAT?!?! 9000?!?!
end.

Remarks

Can you make a game like this? Can you make it keep track of the number of games in a session and your highest and average score?

Programming - a skill for life!

Student programs to inspire you!