Space Game

 
 

program Space;

uses Common, QuickDrawII, EventMgr, MscToolSet;


const

  MAX_ROCKS = 5;


type

  Star = Object

    x, y, speed, color: Integer;

    procedure setup;

    procedure draw;

  end;


  Rock = Object

    x, y, speed: Integer;

    procedure setup;

    procedure draw;

    procedure reset;

    function hasCollided(pos: Integer): Boolean;

    function hasDestroyed(pos: Integer): Boolean;

  end;


var

  i, j, x, y, pos, score: Integer;

  tick: longInt;

  mouse: Point;

  stars: Array[0..31] of Star;

  rocks: Array[1..MAX_ROCKS] of Rock;

  gameOver: Boolean;

  str: String;


{ Star }


procedure Star.setup;

begin

  x := randomInteger mod 320;

  y := randomInteger mod 200;

  speed := randomInteger mod 5 + 1;

  color := randomInteger mod 15 + 1;

end;


procedure Star.draw;

begin

  setSolidPenPat(black);

  moveTo(x, y);

  line(0, 0);


  y := y + speed;

  if y > 199 then begin

    y := 0;

    speed := randomInteger mod 5 + 1;

  end;


  setSolidPenPat(color);

  moveTo(x, y);

  line(0, 0);

end;


{ Rock }


procedure Rock.setup;

begin

  x := randomInteger mod 310;

  y := randomInteger mod 100;

  speed := randomInteger mod 3 + 1;

end;


procedure Rock.draw;

var

  r: Rect;


begin

  setRect(r, x, y, x + 10, y + 10);

  eraseOval(r);


  y := y + speed;

  if y > 190 then begin

    x := randomInteger mod 310;

    y := 0;

    speed := randomInteger mod 6 + 3;

  end;


  setSolidPenPat(2);

  setRect(r, x, y, x + 10, y + 10);

  paintOval(r);

end;


procedure Rock.reset;

var

  r: Rect;


begin

  setRect(r, x, y, x + 10, y + 10);

  eraseOval(r);

  x := randomInteger mod 310;

  y := 0;

  speed := randomInteger mod 6 + 3;

end;


function Rock.hasCollided;

begin

  if (y > 170) and (y < 190) and (x > pos) and

    (x < pos + 20) then hasCollided := true

  else hasCollided := false;

end;


function Rock.hasDestroyed;

begin

  if (x > pos) and (x < pos + 10) then

    hasDestroyed := true

  else hasDestroyed := false;

end;


{ Draw spaceship }


procedure drawShip;

var

  r: Rect;


begin

  setRect(r, pos, 180, pos + 20, 188);

  eraseRect(r);


  getMouse(mouse);

  pos := mouse.h;

  if pos > 300 then pos := 300;


  setSolidPenPat(7);

  setRect(r, pos, 183, pos + 20, 188);

  paintOval(r);

  setSolidPenPat(4);

  setRect(r, pos + 5, 180, pos + 15, 185);

  paintOval(r);

end;


{ Draw stars }


procedure drawStars;

var

  i: Integer;


begin

  for i := 0 to 31 do

    stars[i].draw;

end;


{ Draw rocks }


procedure drawRocks;

var

  i: Integer;


begin

  for i := 1 to MAX_ROCKS do

    rocks[i].draw;

end;


{ Draw explosion }


procedure drawExplosion(x, y, radius, color:

  Integer);

var

  r: Rect;


begin

  setSolidPenPat(color);

  setRect(r, x - radius, y - radius,

    x + 5 + radius, y + 5 + radius);

  paintOval(r);

end;


{ Draw laser }


procedure drawLaser(pos, color: Integer);

begin

  setSolidPenPat(color);

  moveTo(pos + 10, 0);

  lineTo(pos + 10, 179);

end;


{ Main }


begin


  { Setup  }


  startDesk(320);

  clearScreen(black);

  setSolidBackPat(black);

  hideCursor;


  score := 0;

  tick := getTick;

  gameOver := false;

  getMouse(mouse);

  pos := mouse.h;


  for i := 0 to 31 do begin

    new(stars[i]);

    stars[i].setup;

  end;


  for i := 1 to MAX_ROCKS do begin

    new(rocks[i]);

    rocks[i].setup;

  end;


  repeat

    drawStars;

    drawRocks;

    drawShip;


    repeat until getTick > tick;

    tick := tick + 1;


    { Check collision }


    for i := 1 to MAX_ROCKS do begin

      if rocks[i].hasCollided(pos) then begin


      { Explosion }


      x := rocks[i].x;

      y := rocks[i].y;


      for j := 1 to 15 do begin

        drawStars;

        drawRocks;

    drawExplosion(x, y, j * 5, j);


        repeat until getTick - tick > 3;

        tick := getTick;

      end;


      sysBeep;

      gameOver := true;

    end;

  end;


  { Fire laser }


  if button(0) then begin

    drawLaser(pos, white);


    for i := 1 to MAX_ROCKS do begin

      drawStars;


      if rocks[i].hasDestroyed(pos) then begin

        score := score + rocks[i].y div 10;

        rocks[i].reset;

      end;

    end;


    drawLaser(pos, black);

  end;

  until gameOver;


  { Game over }


  moveTo(60, 90);

  setBackColor(black);

  setForeColor(9);

  str := concat('Game Over. Your Score is ',

    cnvis(score), '.');

  drawString(str);

  repeat until button(0);


  for i := 0 to 31 do

    dispose(stars[i]);


  for i := 1 to MAX_ROCKS do

    dispose(rocks[i]);


  endDesk;

end.

Orca/Pascal version, written using Object Pascal to demonstrate object oriented programming.