program Shute (input, output); {Joshua Waller + Philip Hackett Start:27/7/97} {Shoote-em-up/Car?/Calculator Game/Program!!!} {version: 0.0.7 } {last update:05/02/99 } {by :Joshua Waller } uses crt; var {FOR MONSTERS...} monsterx,monstery :array[1..50] of integer; visbulmon :array[1..50] of boolean; numberofmonsters :integer; {FOR SHIP...} shipx,shipy :integer; {FOR BULLETS...} bulletx,bullety :array[1..20] of integer; visbul :array[1..20] of boolean; buldir :array[1..20] of integer; numberofbullets :integer; {max 20 as set up above} {ODD ONES... I think} finish :boolean; bum :char; {bum is used to read keys in and store them} energy :integer; again :char; Weapon :integer; n :integer; {n=used as general count in various counts} delayofmonsters :integer; {delay of monsters=10 v.fast 100 slow} score :LongInt; {players score! can get bigger than 32768} f :INTEGER; {used for procedure FLASH!} {SOUND SETUP...} SoundTable :array[1..5,1..40] of integer; SoundColumn :integer; CurrentSound :integer; SoundActive :boolean; {LEVEL SETUP} Level :integer; {stores level player is on...} {CALCULATOR VARIABLES...} Numberone :real; Numbertwo :real; Operation :string[1]; Output :real; AgainCal :char; Print :char; ncal :boolean; {TITLE BAR VAR} screennumber :integer; {END OF VARIABLES....................} Label Getout; Label Startagain; procedure GAP;begin;writeln;end; PROCEDURE CENTRE (Y:INTEGER;Z:STRING); {CENTRES TEXT ON A LINE OF THE SCREEN} {Y is y co-ord / position, Z is string and C is color} VAR T:INTEGER; BEGIN T:=41-(LENGTH(Z) DIV 2);{CALCULATE CENTRE FOR Z} GOTOXY (T,Y);{MOVE TO T,Y} WRITELN (Z); {WRITE TEXT TO SCREEN} END;{procedure centre} procedure TITLE_BAR; begin TextBackground(Blue); TextColor(white); CENTRE(1,' SHUTE! Version 0.0.7b (C) Phil & Josh 1999 '); GOTOXY(63,1); case screennumber of 1: Writeln(' TITLE SCREEN'); 2: Writeln(' INSTRUCTIONS'); 3: Writeln(' CREDITS'); else Writeln('*****************'); end; TextBackground(Black); TextColor(white); end;{procedure title_bar} Procedure CALC; {CALCULATOR v0.01l Lite} begin; ncal:=false; Repeat; clrscr; Output:=0; Writeln('Calculator v0.01l Lite (C) Josh 97'); Writeln('See INSTRUCTIONS for more information.'); GAP; {************** COLLECTING DATA.. **************} Write('What is you first number: '); Readln(Numberone); Write('What operation would you like to do (*.+.-./): '); Readln(Operation); Write('What is your second number: '); Readln(Numbertwo); {************** WORKING IT OUT... **************} IF Operation='*' then Output:=Numberone*numbertwo; If Operation='/' then Output:=Numberone/numbertwo; If operation='+' then Output:=Numberone+numbertwo; If operation='-' then Output:=Numberone-numbertwo; {************** OUTPUT OF RESULT. **************} Writeln('The answer is: ',Output:2:2); {************** OPTION OF PRINTING INFO ********} Write('Would you like to print your calculation? Y/N: '); Readln(print); Print:=Upcase(print); If print='Y' then begin writeln(Numberone:2:2,operation,numbertwo:2:2,'=',Output:2:2); writeln('Sorry printer feature disabled'); end; {************** OPTION OF RUNNING AGAIN ********} Write('Would you like to run the program again? Y/N: '); Readln(Againcal); Againcal:=Upcase(Againcal); Until Againcal='N'; Write('Thank you for using this program...');Delay(500); end; Procedure Locate(x,y:integer;c:char); Begin; Gotoxy(x,y); Write(c); end; procedure Tcol(colour:integer);begin;TextColor(colour);end; {Tcol procedure saves having to type TextColor every time} procedure INSTRUCTIONS; begin; clrscr; screennumber:=2; TITLE_BAR; Writeln('This game is Freeware.'); GAP; Writeln('In game controls are...'); GAP; Writeln('O - move ship left'); Writeln('P - move ship right'); Writeln('SPACEBAR - Shoot!'); Writeln('W - Change Weapon'); Writeln('B - pause game'); Writeln('Q - quit game'); GAP; GAP; Writeln('Conditions of this game and source type thing...'); GAP; Writeln('This source is provided in good faith, in that if you update it'); Writeln('you will email the following address with the updated version.'); GAP; TCol(3); CENTRE(19,'goshwa@hotmail.com '); TCol(15); GAP; Writeln('So that it can be compiled and published on Josh''s web site... '); GAP; TCol(3); CENTRE(23,'https://members.tripod.com/joshuawaller/'); TCol(15); GAP; Write('Press any key when ready'); REPEAT UNTIL KEYPRESSED; end; procedure CREDITS; {procedure to display credits screen so new coders can add their name} begin; clrscr; screennumber:=3; TITLE_BAR; TCol(3); CENTRE(2,'HERE ARE THE CREDITS'); TCol(14); CENTRE(4,'Initial Development by Joshua Waller and Philip Hackett'); CENTRE(5,'Started the 27th July 1997'); TCol(15); CENTRE(7,'Version 0.0.6b to 0.0.7b developed by Joshua Waller 05/02/99'); CENTRE(8,'Version 0.0.7b to ?.?.? developed by A. Somebody ??/??/??'); CENTRE(9,'Version ?.?.? to ?.?.? developed by A. Somebody Else ??/??/??'); CENTRE(10,'Version ?.?.? to ?.?.? developed by A. Somebody Else ??/??/??'); CENTRE(24,'Press any key when ready'); REPEAT UNTIL KEYPRESSED; end; {procedure CREDITS} procedure Tripleshot(dir:integer); begin; {search for a spare bullet slot} N:=1; While (n<=NumberOfBullets) and (visbul[n] = true) do {this may be a cause of crash!} n:=n+1; {leave if there are none} if n>numberofbullets then exit; {okay - we've got one then...} Locate(shipx,(shipy-1),'*'); Visbul[n]:=true; Bulletx[n]:=shipx; Bullety[n]:=shipy-1; Buldir[n]:=dir; {straight up}; end; {** Sound Section of procedures... ******************************************} procedure StartSound(SoundNumber:integer); begin SoundColumn:=1; CurrentSound:=SoundNumber; SoundActive:=true; end; procedure DoSound; var a,n:integer; begin if soundactive then begin a:=SoundTable[currentsound,soundcolumn]; if (a=0) and (soundcolumn<=40) then begin soundactive:=false; NoSound; delay(5); end else begin for n:=1 to 5 do begin sound(a); delay(1); nosound; end; end; end; soundcolumn:=soundcolumn+1; end; procedure SetUpSounds; {*** SOUND SET UP BY PROGRAMMER ***} var n:integer; begin {sound 1} for n:=1 to 2 do soundtable[1,n]:=n*100; soundtable[1,6]:=0; {stop here} {sound 2} for n:=1 to 2 do soundtable[2,n]:=n*100+600; soundtable[2,6]:=0; {sound 3} soundtable[3,1]:=1000; soundtable[3,2]:=500; soundtable[3,3]:=0; {sound 4 - collision} soundtable[4,1]:=2000; soundtable[4,2]:=2000; soundtable[4,3]:=0; end; {** ship procedure in here... ***********************************************} procedure SHADOW; VAR OnOff:integer; {creates and maintains ships shadow} begin; TCol(6); {shipshadow = ? } OnOff:=Random(2); if OnOff=1 then begin; Locate(Shipx,Shipy+1,''); end; if OnOff=0 then begin; Locate(Shipx,Shipy+1,' '); end; end; {** Bullet Controlling Section of procedures... *****************************} procedure SHOOT; begin; {search for a spare bullet slot} N:=1; While (n<=NumberOfBullets) and (visbul[n] = true) do {this may be a cause of crash!} n:=n+1; {leave if there are none} if n>numberofbullets then exit; {okay - we've got one then...} Locate(shipx,(shipy-1),'*'); Visbul[n]:=true; Bulletx[n]:=shipx; Bullety[n]:=shipy-1; Buldir[n]:=0; {straight up}; if weapon=0 then StartSound(3); if weapon=1 then begin BulDir[n]:=-1+random(3); StartSound(1); end; if weapon=2 then begin TripleShot(0);TripleShot(-1);TripleShot(1); StartSound(2) end; end; PROCEDURE MOVEBULLETS; begin; {get present position of bullet(s)} For n:=1 to numberofbullets do begin; {clearing old bullet(s)} If visbul[n] then begin; Locate(bulletx[n],bullety[n],' '); {} bullety[n]:=bullety[n]-1; bulletx[n]:=bulletx[n]+buldir[n]; {} if (bullety[n]>=1) and (bulletx[n]>=1) and (bulletx[n]<=79) then {happy - not off screen, so draw it} locate(bulletx[n],bullety[n],'*') else visbul[n]:=false; {off screen - kill it} {} end; end; end; procedure DETECTCOLLISIONS;{for bullets + monsters} var n,m:integer; {sets up fresh integers coz you can't use n for two seperate things} begin; for n:=1 to 20 do for m:=1 to 50 do begin {if they exist then do...} If (visbul[n]=true) and (visbulmon[M]=true) then begin {if they are in same position then do...} If (bulletx[n]=monsterx[M]) and ((bullety[n]=monstery[M]) or (bullety[n]-1=monstery[m])) then begin {make monster invisible} visbulmon[M]:=false; numberofmonsters:=numberofmonsters-1; {get rid of monster from total amount} visbul[n]:=false; {make bullet invisible} locate(bulletx[n],bullety[n],' '); {clear position where the BULLET iz} locate(monsterx[m],monstery[m],' '); {clear the position you fat controller} score:=score+100; end; end; end; end; {** Monster Section... ******************************************************} Procedure StartMonsters; begin Tcol(15); {monster colour 4=red(too dark), 6=brown, 15 = white!} FOR n:=1 to 50 do {** setting up initial position of monsters **} begin monsterx[n]:=random(79)+1; {randomly} monstery[n]:=random(25)+1; visbulmon[n]:=false; end; for n:=1 to numberofmonsters do begin visbulmon[n]:=true; {not false} Locate(Monsterx[n],Monstery[n],'#'); {Character of monster *HERE*} end; FOR n:=1 to 20 do {** making bullets invisible **} begin visbul[n]:=false; end; Shipx:=40;Shipy:=24;{** makes sure ship is in centre start of each level *} end; {*** wow! they completed the entire game!! ***} procedure ClockedEntireGameSequence; begin Clrscr; Writeln('You completed the entire game, woopee doo.'); Writeln('Aren''t you clever!'); end; {*** Level stuff... *******************************************************} procedure LEVELDISPLAY; {shows player what level they are entering moo moo} begin Level:=Level+1; {increses level number as player has got to the next level} clrscr; Tcol(14); {text color yellow} Gotoxy(36,12); Write('LEVEL ',Level); Delay(2000); clrscr; StartMonsters; end; procedure WELLDONE; {this pops up when all monsters have been killed...} begin Tcol(10); {Text Green} Gotoxy(36,12); Write('WELL DONE'); Delay(2500); DelayofMonsters:=DelayofMonsters-5; {makes next level harder... by speeding up by 5} Numberofmonsters:=20; {set number of monster back to 20} LEVELDISPLAY; If level=20 then {so far limited to 20 levels...} begin; ClockedEntireGameSequence; {calls well done smart arse cangratulations screen} finish:=true; {exits game loop when they get to level 50} end; end; {** Others... ***************************************************************} procedure MENU; {title screen and menu} begin clrscr; screennumber:=1; TITLE_BAR; Tcol(15); CENTRE(2, '*** Please run full screen DOS, not in a window. ***'); {GAP;} GAP; TCol(3); CENTRE(5, '1 PLAY GAME'); TCol(15); CENTRE(7, '2 INSTRUCTIONS'); CENTRE(8, '3 CREDITS'); TCol(6); CENTRE(10, 'C CALCULATOR'); TCol(4); CENTRE(12, 'Q QUIT GAME'); TCol(15); GAP; Gotoxy(31,15); Write('->'); Repeat Gotoxy(33,15);ClrEol;Gotoxy(33,15); {ClrEol clears rest of line} READ(AGAIN); AGAIN:=Upcase(AGAIN); Until (AGAIN='1') or (AGAIN='2') or (AGAIN='3') or (AGAIN='Q') or (AGAIN='C'); end; {procedure MENU} procedure INTERPRETKEYINPUTS; {this is where it decides to do with the keys} begin {pressed by the player....} bum:=readkey; if bum='q' then finish:=true; if bum='o' then begin Locate(shipx,shipy,' '); Locate(shipx,shipy+1,' '); shipx:=shipx-1; If shipx<1 then shipx:=1; end; if bum='p' then begin Locate(shipx,shipy,' '); Locate(shipx,shipy+1,' '); shipx:=shipx+1; If shipx>79 then shipx:=79; end; if bum='b' then REPEAT UNTIL KEYPRESSED; if bum=' ' then SHOOT; if bum='w' then weapon:=(weapon+1) mod 3; end; {** PROCEDURE INTERPRETKEYINPUTS **} procedure SCREENDISPLAY; {puts info like energy/score/weapon type on screen} begin TextBackground(blue); CENTRE(1, ' '); Gotoxy(1,1); if Energy >=50 then TCol(10); if ((Energy >=30) and (Energy <50)) then TCol(14); if Energy <=20 then TCol(red); Write(' Energy '); Write(Energy); Gotoxy(13,1); Tcol(14); Write(' Score ',Score); Gotoxy(28,1); {temp display? during development only?} Tcol(11); Write(' Delay ',Delayofmonsters,' '); Gotoxy(40,1); Tcol(12); Write(' Monsters Left ',numberofmonsters,' '); Gotoxy(60,1); TCol(13); case weapon of 0 : Write(' WEAPON : NORMAL '); 1 : Write(' WEAPON : SPLIT BEAM '); 2 : Write(' WEAPON : TRIPLE '); end; TextBackground(black); end;{proc screendisplay} procedure Flash; {flashes screen} begin If F=1 then begin; TextBackground(Red); clrscr; delay(30); {is 30 the right length?????~?????????} F:=2 end; If F=2 then begin; TextBackground(Black); clrscr; end; F:=0; {resets so that next time it'll go black again!} end; procedure ClearAnythingLurkingAboutFromPreviousActionsOfComputer; {pretty clear what this does eh? - ie if previous program had blue background} {this makes sure that in this program it's gonna' be okay! } begin TextBackground(Black); end; procedure SetUpBeginningSettings; {*** SETS UP CERTAIN GLOBAL BEGGINNING SETTINGS>>>} begin Weapon:=0; {defaults player to Normal weapon before start of all games} numberofbullets:=10; {MAX 20!} {sets beginning no. of bullets...} numberofmonsters:=20; {sets beginning no. of monsters...} Level:=0; {Level is changed to 1 within LevelDisplay!} Delayofmonsters:=100; {Speed of whole game really/10 v.fast 100slower etc...0 AS FAST AS YOUR PC CAN GO!!} Energy:=100; {beginning amount of energy...} end; {of SetUpBeginningSettings } procedure EndItAll; begin GAP; GAP; Nosound; CENTRE(17,'Thank you for playing...'); DELAY(1500); end; {End It all proc} {****************************************************************************} {* MAIN PROGRAM *} {****************************************************************************} begin; ClearAnythingLurkingAboutFromPreviousActionsOfComputer; {*** PROC ***} Repeat; {** LOOP BEGINNING TO GO BACK TO TITLE SCREEN WHEN GAME LOOP FINISHES ***} Startagain: {this used so that after calc it doesn't go straight into game!} MENU; {*** CALLS MENU PROCEDURE... ***} if again='Q' then goto GetOut; {exit:funny command that exits from current procedure} if again='2' then INSTRUCTIONS; {calls instructions screen} if again='3' then CREDITS; {*** PROC ***} if again='C' then CALC; {*** CALLS CALC PROCEDURE ***} if (again='C') or (again='2') or (again='3') then goto Startagain; SetUpSounds; {*** PROC ***} finish:=false; SetUpBeginningSettings; {*** PROC ***} {*** STARTING PLAYING GAME SECTION OF GAME...} LEVELDISPLAY; {calls procedure to tell player what level they are on} {Level display also calls procedure StartMonsters} Repeat; {**** MAIN GAME LOOP!!!! ****} SCREENDISPLAY; {*** PROC ***} TCol(14); {ShipColour = YELLOW!} Locate(Shipx,Shipy,''); SHADOW; {*** PROC *** Ships Shadow} TCol(15); {MONSTER COLOUR - White!!} {*** MONSTER/COLLISION DETECT (between monster and ship) LOOP!! ***} For n:=1 to 50 do begin if visbulmon[n] then {if monster has been shot then never move it around, or let it kill the space-explorer} begin Locate(Monsterx[n],Monstery[n],' '); Monstery[n]:=Monstery[n]+1; If Monstery[n]=26 then begin; Monstery[n]:=1; Monsterx[n]:=random(79)+1; end; Locate(Monsterx[n],Monstery[n],'#'); If (Monsterx[n]=Shipx) and (Monstery[n]=Shipy) then begin Energy:=Energy-10; {*** POW *** Collision = Energy 10 taken!} F:=1; {turns flash on!} StartSound(4); end; If Energy<=0 then finish:=true; {If Energy = Zilch (0) then GAMe OVEr} end; flash; {calls flash proxcedure and if collision occured then it'll flash!} end; {*** ENDS HERE!!! ***} Tcol(12); {bullet colour} MOVEBULLETS; {Calls MOVE BULLETS procedure...} DETECTCOLLISIONS; {Calls... etc. Collision Detection between monster and bullet} DoSound; DELAY(Delayofmonsters); Tcol(14); If numberofmonsters=0 then WELLDONE;{when they've killed all monsters...} {*** READING KEY INPUTS... *** - CALLS INTERPRETKEYINPUTS PROCEDURE.} if keypressed then INTERPRETKEYINPUTS; Until finish; {**** END OF MAIN GAME SECTION LOOP!!! ****} Tcol(15); CENTRE(12,'GAME OVER - PRESS ANY KEY'); DELAY(1500); Until AGAIN='Q'; {***** END OF ENTIRE PROGRAM LOOP ie END OF PROGRAM!!!! ****} GetOut: EndItAll; {*** PROC ***} end. {****************************************************************************} {* END OF MAIN PROGRAM *} {****************************************************************************} *** GAME NOTES *** :) Completed features... { or  for ship.} (*beware of sound messing with game fluidity.*) {SOUND ENHANCEMENTS : multitasking sound!} {shooting- some sort of array of bullets holding X,Y and visible(true/false) and bullet y:=y-1 over and over again until hit top of screen, then bullet becomes invisible, and you can use that bullet again then if monster position = bullet position then score+20(?) monster must dissapear and player could get to next level by killing all 20 monsters... } {menu option(s)... C... Calculator... }v0.05{ includes levels, where the further you get the harder it gets etc.. this update 15/9/97 (implemented within procedure WELLDONE) {also implemented within LEVELDISPLAY} {general game improvements done / ie - code tidied up more. {v0.05 BUGS FIXED... {* When energy goes down due to being hit by a monster the delay also goes down meaning that the game speeds up.*** fixed *** * When the next level is started the monsters aren't started... and therefore don't appear.. *** fixed *** * Was much smoother on my 486 dx2/50 speed/fluidity keeps changing without considering the delay problems... *** fixed *** * LEVEL 2 stays on screen... *** fixed *** }v0.06{ FLASH procedure, it flashes when player is hit by monster, also involves the integer F, when this is 1 it makes the screen white when it is 2 it makes it black and 0 is nonactive... Congratulations screen added when player completes the whole game... Very basic so far but allows future upgrade... see procedure ClockedEntireGameSequence BUGS FIXED... when score becomes greater than 32768 it goes funny... but not anymore!! :) }v0.0.7b Joshua Waller 05/02/99{ Just general stuff done mainly, cleaning up some more stuff so that code isn't in the main section so much. also implemented the use of TITLE_BAR procedure, and CENTRE procedure. made energy change colour so that at certain levels of energy left it is of a certain colour to indicate danger levels. CREDITS screen added so that future developments by people can be aknowledged. Colour added to title screen selections also... fixed bug where if theplayer was still pressing keys and it was game over, now it doesn't instantly take them to menu, it delays(1500) first becuase people were dying and not getting a chance to see what was going on and they were like 'hey what happened?' added "fire tail" to ship and it flashes too!!!! as mentioned in future additions... "If you were to move ship up 1 place so that it's not a very bottom of screen you could allow a tail of fire to be below... it could be red, or orange and be a  or something, as long as it doesn't look like a red reflection of the space ship!" }potential future additions...{ {*When hit by monster/coin/heart have diff sound effects... like bang/crash when hit by monster... and ka-ching(?) when hit by coin... (sound(2000)+ for coin) and soopup sound for heart... (*shooting monsters.(monsterz that shoot back!).. coins... etc... coins - as well as X,Y for asteroids, maybe have a object type e.g. 1-asteroid, 2-coin or maybe, a seperate array for coins with X,Y (just like monsters) but must have it`s own loop bit then (for coins:=1 to 10 do...) different coloured monster, hearts, coins etc.. coins for score, hearts for energy... moving pattern aliens... bases ie SPACE INVADERS... subgame for collecting special token which allows you to play Mat's Car game (the basic one he did for Amstrad + others)... Here are some chars you may want... there looks to be apossibility of more than one type of alien ie @, # etc... . . . . . . . .*                  *=dot is to mark possibilities... Menu options... 3... Game Options... Key setup / Start Difficulty / Sound On/Off / Colour/Mono ALSO! A special cheat section especially for the programmer so that he can have access to ALL variable settings whilst running the game! (also player would like it too...) 4... See }Hi-Score Table{... v0.0.8 ?? Score is increased by 1) shooting monsters... {got this one!} { 2) lasting longer in the game 3) coins... 4) Special bonus levels... ie Car game! + others.. At certain score levels extra energy could be given. Difficulty is increased by making Delayofmonsters smaller... or more monsters... Difficulty could be increased when A) the players score has reached certain levels or... B) when a certain amount of time has passed. by. MORE CHARS... or @ for monstars WEAPON : HOMING MISSILE... Level Display included before each play... Could be included during play... More interest could be added by changing the play size? Maybe? ************************* }Get rid of cursor!!{ **************************** Add a timer:? So that when the time is up they must have killed at more than half the monsters before they can go to the next level? They could get a bonus if they killed all and had some time left! ARE YOU SURE YOU WANT TO QUIT? could flash the ship on/off for a while... } BUGS DISCOVERED IN THIS VERSION (v0.05beta...) INCLUDE...{ }not fixed yet{ * If key held for too long it pauses and goes beeeeeeeeeeep!!! * When paused, if same key is pressed in an attempt to un-pause it, it goes for one loop then stops again... ie- slow motion, should not be allowed!! * Crashes when MENU input is too long! ....see seeme!.txt on a: ???? ****************************************** * TOO EASY AND TOO BORING!!!!!!! * ****************************************** } ***************************************************************************** * SHUTE.PAS is OpenCode - like Linux! See Instructions and Credits * *****************************************************************************