Skip to content

Instantly share code, notes, and snippets.

@jclulow
Created April 17, 2017 23:51
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jclulow/3eb2802f39d21556b7e48576c716be19 to your computer and use it in GitHub Desktop.
Save jclulow/3eb2802f39d21556b7e48576c716be19 to your computer and use it in GitHub Desktop.
{
ASTEROID INVADERS ][
Designed and Coded by
Joshua Clulow
Current Version: 5.0
This program is freeware and
is Intellectual Property of
EspressoFile Concepts.
}
PROGRAM GraphInit;
USES
Crt,Graph,BGIDriv;
TYPE
type_hiScoreEntry=RECORD
name:string[15];
score:integer;
END;
type_hiScoreTable=FILE OF type_hiScoreEntry;
type_hiScoreVariable=ARRAY[-1..9] OF type_hiScoreEntry;
CONST
{VERSION NUMBER}
VERSION_NUMBER = '5.0 FREEWARE RELEASE';
{SPEEDS}
ASTEROID_SPEED = 15;
BULLET_SPEED = 9;
GAME_UPDATE_DELAY = 30;
{GRAPHICS POSITIONING CODES}
XBIAS = 140;
YBIAS = 0;
{INPUT CODES}
NULL = 0;
LEFT = 1;
RIGHT = 2;
SHOOT = 3;
SOUNDT = 4;
QUIT = 5;
SCOREUP = 9;
HEALTH2 = 7;
TIME = 8;
{GAME STATES}
FIRSTLOOP = 0;
TERMINATE = 1;
SOUND_OFF = 2;
SOUND_ON = 3;
SHOOTING = 4;
MOVE_LEFT = 5;
MOVE_RIGHT = 6;
DEAD = 7;
QUITTED = 8;
{GRAPHICS SCREEN COLOURS}
BLACK = 0;
BLUE = 1;
GREEN = 2;
CYAN = 3;
RED = 4;
MAGENTA = 5;
BROWN = 6;
LIGHTGRAY = 7;
DARKGREY = 8;
LIGHTBLUE = 9;
LIGHTGREEN = 10;
LIGHTCYAN = 11;
LIGHTRED = 12;
LIGHTMAGENTA = 13;
YELLOW = 14;
WHITE = 15;
LABEL
1;
VAR
x:integer;
hiScoreFile:type_hiScoreTable;
hiScoreVariable:type_hiScoreVariable;
grDriver,grMode:integer;
asteroidXPos:ARRAY[1..5] OF longint;
asteroidYPos:ARRAY[1..5] OF longint;
asteroidExists:ARRAY[1..5] OF boolean;
shipXPos,gameState,inputLevel:integer;
timer,score,counter:integer;
countstring,timestring,scorestring,healthstring:string;
xxxxx:integer;
bulletExists:boolean;
bulletXPos,bulletYPos:integer;
penalty:integer;
health,currentHiScore:integer;
playAgain:boolean;
xw,xw5:char;
lastpage,currentpage:word;
procedure WaitRetrace;
assembler;
asm
mov dx,3dah
@@loop1: {Wait for display}
in al,dx
test al,08h
jnz @@loop1
@@loop2: {Wait for retrace}
in al,dx
test al,08h
jz @@loop2
end;
PROCEDURE StartGraph; {STANDARD GRAPHICS INIT, EGAlo, 640/350}
BEGIN
registerbgidriver(@EGAVGAdriverproc);
grDriver:=3;
grMode:=1;
InitGraph(grDriver,grMode,'');
END;
PROCEDURE titleScreen; {TITLE SCREEN AND *NO* START MUSIC!}
VAR
x,starX,starY:integer;
BEGIN
randomize;
x:=0;
setColor(WHITE);
WHILE x < 100 DO
BEGIN
{sound((x+400)*2);}
starX := random(640);
starY := random(480);
line(starX,starY,starX,starY);
inc(x);
delay(10);
END;
{ delay(100);
nosound;
}
{sound(1500);}
{ delay(100);
nosound;
}
{sound(250);}
{ delay(50);
nosound;
}
setColor(LIGHTGREEN);
setTextJustify(CenterText,CenterText);
setTextStyle(defaultFont,HorizDir,3);
outTextXY(320,130-80,'ASTEROID INVADERS ][');
setTextStyle(defaultFont,HorizDir,1);
setcolor(lightred);
outTextXY(400+50,165-90,'Deluxe Edition');
setcolor(lightgreen);
settextstyle(defaultfont,horizdir,1);
settextJustify(righttext,BottomText);
outtextxy(639,339,'Copyright (C) 2001 EspressoFile Concepts');
outtextxy(639,349,'Version '+VERSION_NUMBER);
settextjustify(lefttext,bottomtext);
outtextxy(1,339,'Designed and Coded by Joshua Clulow');
outtextxy(1,349,'E-MAIL: liaisons@espressofile.cjb.net');
setTextJustify(LeftText,TopText);
{rectangle(1,1,639,349);}
END;
PROCEDURE displayInstructions; {INSTRUCTIONS TO SUPERIMPOSE ON TITLE SCREEN}
BEGIN
setColor(LIGHTBLUE);
setTextJustify(CenterText,CenterText);
setTextStyle(defaultFont,HorizDir,1);
outTextXY(320,200,'Press left and right arrow keys to move left and right');
outTextXY(320,240,'Press Space to Shoot');
outTextXY(320,290,'Press Q to quit');
setTextJustify(LeftText,TopText);
END;
PROCEDURE setFontSize(fontSize:integer);
BEGIN
setTextStyle(defaultFont,HorizDir,fontSize);
END;
FUNCTION getInput:integer; {CHARACTER READER}
VAR
temp:array[1..2] OF char;
temp2,temp3:char;
BEGIN
IF keypressed THEN temp[1] := readkey;
IF ORD(temp[1])=0 THEN temp[2] := readkey;
temp3 := upcase(temp[1]);
CASE temp3 OF
{ 'Z':getInput := LEFT;
'X':getInput := RIGHT;}
'S':getInput := SOUNDT;
' ':getInput := SHOOT;
'Q':getInput := QUIT;
'#':getInput := HEALTH2;
'^':getInput := TIME;
'(':getInput := SCOREUP;
ELSE
If ORD(temp[1])=0
Then BEGIN
CASE ORD(temp[2]) OF
{ 72:u}
{ 80:d }
75:getInput := LEFT;
77:getInput := RIGHT;
END;
END;
IF ORD(temp[1])<>0 THEN getInput := NULL;
END;
END;
PROCEDURE drawSprites(colour:integer);
VAR
asteroidNumber:integer;
xTemp,yTemp:integer;
sss:integer;
BEGIN
setColor(colour);
FOR asteroidNumber := 1 TO 5 DO
BEGIN
IF asteroidExists[asteroidNumber] THEN
BEGIN
xTemp := XBIAS + AsteroidXPos[asteroidNumber];
yTemp := YBIAS + AsteroidYPos[asteroidNumber];
sss := 1;
WHILE sss < 16 DO
BEGIN
circle(xtemp,ytemp,sss);
inc(sss,2);
END;
{rectangle(xTemp,yTemp,xTemp+32,yTemp+32);}
END;
END;
END;
PROCEDURE quitMessage;
BEGIN
END;
PROCEDURE asteroidPosUpdate;
VAR
s,temp,tempX,tempY,temp1,temp2,ss,sss:integer;
astOK,astOKX,astOKY:boolean;
BEGIN
s := 0;
FOR s := 1 TO 5 DO
BEGIN
temp := random(100);
temp := temp MOD 3;
IF NOT(asteroidExists[s]) AND (temp = 0) THEN
BEGIN
astOK := false;
randomize;
WHILE NOT(astOK) DO
BEGIN
tempX:=random(320);
tempY:=0;
ss := 0;
astOK := True;
FOR ss := 1 TO 5 DO
BEGIN
IF NOT(ss IN [s])
{THEN IF NOT((tempX + 32) <= (asteroidXPos[ss]+1))
THEN IF NOT(tempX+1 <= (asteroidXPos[ss]+32))
{THEN IF NOT(asteroidYPos[ss] IN [(tempY-32)..(tempY+32)])
THEN astOK := true;
{astOK := FALSE;}
THEN BEGIN
astOkX := true;
astOkY := true;
FOR sss := -31 TO 31 DO
BEGIN
IF tempX = asteroidXPos[ss] + sss THEN astOkX := False;
IF tempY = asteroidYPos[ss] + sss THEN astOkY := False;
IF (astOkX = false) AND (astOkY = false) THEN astOk := false;
END;
END;
END;
END;
asteroidXPos[s] := tempX;
asteroidYPos[s] := tempY;
asteroidExists[s] := true;
END;
END;
FOR sss := 1 TO 5 DO
BEGIN
temp1 := asteroidYPos[sss];
temp2 := 150+175+32;
IF asteroidExists[sss] AND (temp1 < temp2) THEN Inc(asteroidYPos[sss],ASTEROID_SPEED)
ELSE asteroidExists[sss] := false;
END;
END;
PROCEDURE bulletSpawn;
BEGIN
IF NOT(bulletExists) THEN
BEGIN
bulletExists := true;
bulletXPos := shipXPos + 16;
bulletYPos := 150+175-32;
END;
END;
PROCEDURE drawBang(xposme,yposme,colourme,size:integer);
VAR
xxxxxx,dddd:integer;
BEGIN
FOR xxxxx := 1 TO 16 DO
BEGIn
dddd := getcolor;
setcolor(colourme);
circle(xposme+XBIAS,yposme+YBIAS,xxxxx*size);
setcolor(dddd);
END;
END;
PROCEDURE bulletPosUpdate;
var
ss,sss:integer;
astok,astokx,astoky:boolean;
BEGIN
IF bulletExists THEN
BEGIN
dec(BulletYPos,2);
IF bulletYPos <= 0 THEN bulletexists := false;
FOR ss := 1 TO 5 DO
BEGIN
astOkX := true;
astOkY := true;
astOk:=true;
FOR sss := -16 TO 16 DO
BEGIN
IF bulletxPos = asteroidXPos[ss] + sss THEN astOkX := False;
IF bulletyPos = asteroidYPos[ss] + sss THEN astOkY := False;
IF (astOkX = false) AND (astOkY = false) THEN astOk := false;
END;
IF NOT(astOK) THEN
BEGIN
setactivepage(currentpage);
asteroidExists[ss] := false;
drawBang(asteroidXPos[ss],asteroidYPos[ss],YELLOW,2);{
delay(10);
drawBang(asteroidXPos[ss],asteroidYPos[ss],BLACK,2); }
bulletexists := false;
inc(score,10);
END;
END;
END;
END;
PROCEDURE bulletErase;
var
v:integer;
BEGIn
{ setcolor(black);
IF bulletexists THEN
BEGIn
FOR v := -2 TO 1 DO rectangle(XBIAS+bulletXpos+v,YBIAS+bulletYPos+v,XBIAS+bulletXpos-v,YBIAS+bulletypos-v);
END; }
END;
PROCEDURE shipCrashDetect;
VAR
astok,astokx,astoky:boolean;
sss,ss:integer;
BEGIN
FOR ss := 1 TO 5 DO
BEGIN
astOk := true;
astOkX := true;
astOky:=true;
FOR sss := -32 TO 32 DO
BEGIN
if asteroidexists[ss] THEN
begin
IF shipXPos+8
= asteroidXPos[ss] + sss THEN astOkX := False;
IF (150+175-16) = asteroidYPos[ss] + sss THEN astOkY := False;
IF (astOkX = false) AND (astOkY = false) THEN astOk := false;
end;
END;
if not(astok) THEN
begin
setactivepage(currentpage);
dec(health,1);
{ drawsprites(black);}
asteroidexists[ss] := false;
drawbang(shipxpos+16,150+175-16,YELLOW,4);
{ delay(10);}
inc(penalty,4);
{ drawbang(shipxpos+16,150+175-16,BLACK,4);}
end;
END;
END;
PROCEDURE bulletDraw;
BEGIN
IF bulletExists THEN
BEGIN
setcolor(GREEN);
rectangle(XBIAS+bulletXpos-2,YBIAS+bulletYPos-2,XBIAS+bulletXpos+2,YBIAS+bulletypos+2);
setfillstyle(1,LIGHTGREEN);
floodfill(XBIAS+bulletXPos,YBIAS+bulletYPos,GREEN);
END;
END;
PROCEDURE hiScoreShift(slot2StartFrom,ScoreToPutThere:integer;name2PutThere:string);
VAR
x5:integer;
BEGIN
FOR x5 := 9 DOWNTO slot2StartFrom DO
BEGIN
hiScoreVariable[x5].name := hiScoreVariable[x5-1].name;
hiScoreVariable[x5].score := hiScoreVariable[x5-1].score;
END;
hiScoreVariable[slot2StartFrom].name := Name2PutThere;
hiScoreVariable[slot2StartFrom].score := ScoreToPutThere;
END;
function FileExists(FileName: String): Boolean;
{ Boolean function that returns True if the file exists;otherwise,
it returns False. Closes the file if it exists. }
var
F: file;
begin
{$I-}
Assign(F, FileName);
FileMode := 0; { Set file access to read only }
Reset(F);
Close(F);
{$I+}
FileExists := (IOResult = 0) and (FileName <> '');
end; { FileExists }
FUNCTION getHiScoreName:string;
VAR
temp44:string;
BEGIN
writeln;
writeln('WOW! YOU GOT A HIGH SCORE!');
writeln;
write('PLEASE ENTER YOUR NAME (15 LETTERS MAX) : ');
readln(temp44);
getHiScoreName := temp44;
END;
PROCEDURE createHiScores;
VAR
hiScoreVariableTemp:type_hiScoreVariable;
x5:integer;
BEGIN
assign(hiScoreFile,'hiscore.jmc');
rewrite(hiScoreFile);
FOR x5 := 9 DOWNTO 0 DO
BEGIN
hiScoreVariableTemp[x5].name := 'Joshua';
hiScoreVariableTemp[x5].score := (x5+1) * 100;
END;
FOR x5 := 9 DOWNTO 0 DO
BEGIN
write(hiScoreFile,hiScoreVariableTemp[x5]);
END;
Close(hiScoreFile);
END;
PROCEDURE hiScoreLoader;
VAR
x5:integer;
BEGIN
IF NOT(fileExists('hiscore.jmc')) THEN createHiScores;
assign(hiScoreFile,'hiscore.jmc');
reset(hiScoreFile);
FOR x5 := 0 TO 9 DO
BEGIN
read(hiScoreFile,hiScoreVariable[x5]);
END;
close(hiScoreFile);
END;
PROCEDURE tabulator(tabsToTab:integer);
BEGIN
gotoXY(tabsToTab,whereY);
END;
PROCEDURE hiScoreSaver;
VAR
x5:integer;
BEGIn
assign(hiScoreFile,'hiscore.jmc');
rewrite(hiScoreFile);
FOR x5 := 0 TO 9 DO
BEGIN
write(hiScoreFile,hiScoreVariable[x5]);
END;
close(hiScoreFile);
END;
BEGIN {MAIN PROGRAM}
StartGraph;
ClearDevice;
titleScreen;
setvisualpage(0);
setactivepage(0);
lastpage:=1;
currentpage:=0;
displayInstructions;
REPEAT UNTIL keyPressed;
readkey;
currentHiScore := 400;
playAgain := True;
WHILE playAgain DO
BEGIN
asteroidexists[1] := false;
asteroidexists[2] :=false;
asteroidexists[3] := false;
asteroidexists[4] := false;
asteroidexists[5] := false;
bulletexists := false;
cleardevice;
gameState := FIRSTLOOP;
timer := 60;
score := 0;
counter := 1;
bulletExists:=false;
penalty := 0;
health := 6;
randomize;
FOR xxxxx := 1 TO 50 DO
BEGIN
putPixel(random(639),random(479),WHITE);
END;
{ setcolor(WHITE);
rectangle(XBIAS-4,YBIAS-16-2,XBIAS+320+16+2,YBIAS+175+48+2);
setfillstyle(1,BLACK);
floodfill(320,175,WHITE);
settextjustify(centertext,centertext);
setcolor(LIGHTGREEN);
outtextXY(XBIAS,20,'ASTEROID INVADERS II');}
WHILE (gameState <> TERMINATE) AND (gameState <> DEAD) AND (gameState <> QUITTED) DO
BEGIN
shipCrashDetect;
IF health < 1 THEN gamestate := DEAD;
asteroidPosUpdate;
for x:=1 to BULLET_SPEED do
begin
bulletPosUpdate;
bulletPosUpdate;
end;
{PAGE SWITCH HERE `````````````````````````~~~~~~~~~}
if lastPage=1 then currentPage:=2 else currentPage:=1;
setactivepage(currentPage);
{ lastPage:=currentPage;}
FOR xxxxx := 1 TO 40 DO
BEGIN
putPixel(random(639),random(479),WHITE);
END;
{ setColor(BLACK);
LINE(XBIAS+shipXpos,YBIAS+175,XBIAS+shipXpos+16,YBIAS+175-32);
LINE(XBIAS+shipXpos+16,YBIAS+175-32,XBIAS+shipXpos+32,YBIAS+175);
LINE(XBIAS+shipXPos,YBIAS+175,XBIAS+ShipXpos+32,YBIAS+175);
}
{ Rectangle((XBIAS + shipXPos),(YBIAS + (175-32)),(XBIAS + shipXPos + 32),(YBIAS + (175-32) + 32));}
inputLevel := getInput;
IF inputLevel = TIME THEN inc(timer,10);
IF inputLevel = HEALTH2 THEN health := 6;
IF inputLevel = SCOREUP THEN inc(score,100);
IF inputLevel < QUIT
THEN IF (inputLevel = LEFT) AND ((shipXPos - 4) >= 1)
THEN shipXPos := shipXPos - 18
ELSE BEGIN
IF (inputLevel = RIGHT) AND ((shipXPos + 4) <= 320)
THEN shipXPos := shipXPos + 18
END
ELSE BEGIN
IF inputLevel = QUIT THEN
begin
gameState := QUITTED;
penalty := 20;
end;
END;
IF inputLevel = SHOOT THEN bulletSpawn;
{setColor(WHITE);
rectangle(1,1,639,479); }
{draSprites;}
{ setColor(GREEN);
Rectangle((XBIAS + shipXPos),(YBIAS + (175-32)),(XBIAS + shipXPos + 32),(YBIAS + (175-32) + 32));
}
str(counter,countstring);
str(timer,timestring);
str(score,scorestring);
setcolor(LIGHTBLUE);
setFontSize(1);
{outTextXY(1,1,'current count is ' + countstring);}
setFontSize(2);
IF (counter MOD 2 = 0) THEN
BEGIN
str(score,scorestring);
END;
str(health,healthstring);
outtextxy(1,80,'HEALTH:');
outtextxy(1,120,healthstring+'/6');
outTextXY(1,160,'SCORE:');
outTextXY(1,200,scorestring);
outTextXY(1,240,'TIME:');
outTextXY(1,280,timestring);
drawSprites(BROWN);
bulletDraw;
setcolor(GREEN);
LINE(XBIAS+shipXpos,YBIAS+150+175,XBIAS+shipXpos+16,YBIAS+150+175-32);
LINE(XBIAS+shipXpos+16,YBIAS+150+175-32,XBIAS+shipXpos+32,YBIAS+150+175);
LINE(XBIAS+shipXPos,YBIAS+150+175,XBIAS+ShipXpos+32,YBIAS+150+175);
setvisualpage(currentPage);
setactivepage(lastpage);
lastpage:=currentpage;
clearviewport;
delay(GAME_UPDATE_DELAY);
shipCrashDetect;
{ setcolor(black);
outtextxy(1,80,'HEALTH:');
outtextxy(1,120,healthstring);
outtextxy(1,160,'SCORE:');
outtextxy(1,200,scorestring);
bulleterase;}
{IF keypressed THEN readkey;}
{ drawSprites(BLACK); }
setcolor(BLACK);
setFontSize(1);
{ outTextXY(1,1,'current count is ' + countstring);}
IF counter = 18 THEN
BEGIN
counter := 1;
inc(score,2);
dec(timer);
{ setcolor(BLACK);
setFontSize(2);
outTextXY(1,175,'TIME:');
outTextXY(1,280,timestring); }
END;
IF timer = 0 THEN gameState := TERMINATE;
inc(counter);
END;
IF GAMESTATE = DEAD THEN
BEGIN
setactivepage(1);
setvisualpage(1);
cleardevice;
drawbang(160,175,YELLOW,32);
delay(800);
drawbang(160,175,RED,16);
delay(600);
drawbang(160,175,WHITE,8);
delay(400);
settextjustify(centertext,centertext);
settextstyle(defaultfont,horizdir,4);
setcolor(LIGHTBLUE);
outtextxy(320,175,'GAME OVER.');
delay(2000);
END;
{COMMENT TO MAKE GAME 500 LINES 1}
{COMMENT 2}
{COMMENT S!}
CloseGraph;
delay(1000);
FOR xxxxx := 1 TO 50 DO IF keypressed THEN Readkey;
writeln;
writeln;
textcolor(WHITE);
writeln('SCORE : ',score);
writeln('PENALTY : ',penalty);
writeln('------------------------');
writeln('FINAL SCORE : ',score-penalty);
writeln;
score := score-penalty;
hiScoreLoader;
IF score > hiscoreVariable[0].score
THEN hiScoreShift(0,score,getHiScoreName)
ELSE IF score > hiScoreVariable[1].score
THEN hiscoreShift(1,score,gethiscorename)
else if score > hiscorevariable[2].score
then hiscoreshift(2,score,gethiscorename)
else if score > hiscorevariable[3].score
then hiscoreshift(3,score,gethiscorename)
else if score > hiscorevariable[4].score
then hiscoreshift(4,score,gethiscorename)
else if score > hiscorevariable[5].score
then hiscoreshift(5,score,gethiscorename)
else if score > hiscorevariable[6].score
then hiscoreshift(6,score,gethiscorename)
else if score > hiscorevariable[7].score
then hiscoreshift(7,score,gethiscorename)
else if score > hiscorevariable[8].score
then hiscoreshift(8,score,gethiscorename)
else if score > hiscorevariable[9].score
then hiscoreshift(9,score,gethiscorename);
writeln('PRESS ANY KEY TO CONTINUE...');
readkey;
clrscr;
writeln('HIGH SCORES');
writeln('===========');
FOR xxxxx := 0 TO 9 DO
BEGIN
write(xxxxx+1,'. ',hiScoreVariable[xxxxx].name);
tabulator(23);
writeln(hiScoreVariable[xxxxx].score);
writeln;
END;
writeln('PRESS R TO RESET HISCORES or ANY KEY TO CONTINUE...');
xw5 := readkey;
xw5 := upcase(xw5);
IF xw5 = 'R' THEN
BEGIN
createHiScores;
hiScoreLoader;
END;
hiScoreSaver;
{ IF (score-penalty) > currentHiScore
THEN BEGIN
currentHiScore := (score-penalty);
writeln('YOU GOT THE NEW HI SCORE! ( ',currentHiScore,' )');
END
ELSE BEGIN
writeln('CURRENT HIGH SCORE IS ',currentHiScore);
writeln('YOU ONLY NEEDED ',currentHiScore-(score-penalty),' TO BEAT IT!');
END;}
writeln;
write('PLAY AGAIN? (Y/N)');
xw:=readkey;
xw := upcase(xw);
writeln(xw);
IF xw = 'Y' THEN playAgain := TRUE ELSE playAgain:=FALSE;
StartGraph;
END;
CloseGraph;
END.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment