'=========================================================================== ' Subject: SPACE WAR!!! Date: 04-01-97 (21:00) ' Author: Gary N. Wilkerson, Jr. Code: QB, QBasic, PDS ' Origin: comp.lang.basic.misc Packet: GAMES.ABC '=========================================================================== ' S P A C E W A R ! ! ! ' 1987..1993 by Gary N. Wilkerson Jr. ' ' If speed of game is too slow, change the SPEEDCONST = 500 line. ' The higher the number, the faster the game will go. ' ' To run this game press Shift+F5. ' To exit Qbasic, press Alt, F, X. ' ' Sparklepause, CalcDelay, Center, and Rest procedures came from ' QBasic Nibbles and Gorillas program which may be found in the DOS ' directory of the hard drive. ' Set default data type to integer for faster game play DEFINT A-Z ' The SINGLE types allow for various angles of motion TYPE AsteroidType Vert AS SINGLE Horiz AS SINGLE DirVert AS SINGLE DirHoriz AS SINGLE Smash AS INTEGER TorF AS INTEGER Shot AS INTEGER END TYPE ' Type for the player array. ' LONG type allows for large scores, while STRING allows only 10 characters. TYPE PlayrType PlayrName AS STRING * 10 Score AS LONG HorizPos AS INTEGER VertPos AS INTEGER HorizDir AS INTEGER VertDir AS INTEGER ShotHoriz AS INTEGER ShotVert AS INTEGER Alive AS INTEGER Shot AS INTEGER Joystick AS INTEGER END TYPE TYPE StickType Min AS INTEGER Max AS INTEGER END TYPE DECLARE SUB Initialize () DECLARE SUB GameSetUp () DECLARE SUB PlaySpWar () DECLARE SUB FindShip () DECLARE SUB TallyScore (Playr) DECLARE SUB FireBullet (Num) DECLARE SUB EndScene () DECLARE SUB ObjectScreen () DECLARE SUB ControlScreen () DECLARE SUB OnOff (text$, cond) DECLARE SUB FuncKeyOn () DECLARE SUB FuncKeyOff () DECLARE SUB FuncKeyDisplay () DECLARE SUB InitPlayArea () DECLARE SUB MoveBullets () DECLARE SUB MoveAstrd () DECLARE SUB Center (row, text$) DECLARE SUB KeyPause () DECLARE SUB SparklePause () DECLARE SUB GetDirections () DECLARE SUB MoveShips () DECLARE SUB DsplyScore (p1&, p2&, cond) DECLARE SUB Explode (p1, p2) DECLARE SUB TimeDsply (cond) DECLARE SUB Rest (t#) DECLARE FUNCTION Yes () DECLARE FUNCTION CalcDelay! () DECLARE FUNCTION ShipShot () ' Constants CONST SPEEDCONST = 500 CONST TRUE = -1 CONST FALSE = NOT TRUE CONST leftbound = 0 CONST rightbound = 599 CONST upbound = 29 CONST downbound = 169 ' Select the graphics screen ' Requires CGA, EGA, VGA, or MCGA Adapters ON ERROR GOTO GraphicsError SCREEN 2: ON ERROR GOTO 0 ' Global variables and graphics arrays size = 4 + INT(((PMAP(40, 0) - PMAP(0, 0) + 1) * 2 + 7) / 8) * (PMAP(30, 1) - PMAP(0, 1) + 1) DIM SHARED OnePlayr%(size), TwoPlayr%(size) DIM SHARED Player(1 TO 2) AS PlayrType DIM SHARED Asteroid%(size), Astrd AS AsteroidType DIM SHARED Joystick(3) AS StickType DIM SHARED Temp$(5) DIM SHARED Lives AS INTEGER DIM SHARED PlayrNum AS INTEGER DIM SHARED SoundOn AS INTEGER DIM SHARED MachSpeed AS INTEGER DIM SHARED Time AS INTEGER DIM SHARED JoyFlag AS INTEGER ' Define what the ships will look like ship$ = "s2h10r15f10r20f10g10l20g10l15e10u20d4nl8d4nl12d4nl16d4nl12d4l8s4" ' Draw player 2's ship and store in array DRAW "bm14,10x" + VARPTR$(ship$): GET (0, 0)-(40, 30), TwoPlayr% ' Draw player 1's ship and store in array CLS DRAW "bm26,20a2x" + VARPTR$(ship$): GET (0, 0)-(40, 30), OnePlayr% ' Define asteroid, draw it, and store in array Asteroid$ = "BM5,10r5h5r5f5e5f5e5r5g5r5d5g5r5d5l15h5g5l5u5e5h5" CLS : DRAW Asteroid$: GET (0, 0)-(40, 30), Asteroid% Initialize DO ObjectScreen ControlScreen GameSetUp InitPlayArea FuncKeyOn PlaySpWar EndScene COLOR 15, 0: Center 22, "Play again" LOOP WHILE Yes SYSTEM GraphicsError: ' This system does not have a color graphics adapter CLS : Center 11, "Sorry you must have CGA, EGA, VGA, or MCGA Adapters" Center 12, "To play SPACE WAR" PRINT : SYSTEM StickError: ' This system does not support joysticks JoyFlag = FALSE RESUME NEXT HelpScreen: FuncKeyOff DO SCREEN 0: CLS COLOR 14, 0 Center 8, "Space War Help Screen" COLOR 10, 0: Center 11, "Press [ESC] to see the player controls" Center 12, "Press [ENTER] to see the object screen" Center 17, "Press any other key to continue" SELECT CASE INPUT$(1) CASE CHR$(27): ControlScreen CASE CHR$(13): ObjectScreen CASE ELSE: EXIT DO END SELECT LOOP InitPlayArea FuncKeyOn RETURN DosHide: FuncKeyOff SCREEN 0: COLOR 7, 0: CLS SHELL InitPlayArea FuncKeyOn RETURN SoundToggle: SoundOn = NOT SoundOn FuncKeyDisplay RETURN Pause: FuncKeyOff Center 11, "Game Paused" Center 12, "Press any key to continue" SLEEP Center 11, SPACE$(11) Center 12, SPACE$(25) FuncKeyOn RETURN Quit: FuncKeyOff Center 11, "You pressed [QUIT]!" Center 12, "Are you sure" IF Yes THEN SYSTEM Center 11, SPACE$(19) Center 12, SPACE$(22) FuncKeyOn RETURN 'CalcDelay: ' Checks speed of the machine. FUNCTION CalcDelay! s! = TIMER DO i! = i! + 1 LOOP UNTIL TIMER - s! >= .5 CalcDelay! = i! END FUNCTION ' Center, centers (text$) on given (row.) SUB Center (row, text$) LOCATE row, 40 - LEN(text$) / 2 PRINT text$; END SUB ' ControlScreen displays the games controls SUB ControlScreen CLS COLOR 15 Center 7, " Game Controls " Center 9, " General Player 1 Player 2 " Center 10, " (Up) (Up) " Center 11, " " + CHR$(24) + " W " Center 12, " (Left) " + CHR$(27) + " " + CHR$(26) + " (Right) (Left) A D (Right) " Center 13, " " + CHR$(25) + " S " Center 14, " (Down) (Down) " Center 16, " (Fire) [ESC] (Fire) [SPACE]" Center 24, "Press any key to continue" SparklePause END SUB ' DsplyScore displays the players' scores SUB DsplyScore (p1&, p2&, cond) ' Tally the score and keep it within LONG INT's limits Player(1).Score = (Player(1).Score + p1&) AND &H7FFFFFFF Player(2).Score = (Player(2).Score + p2&) AND &H7FFFFFFF Lives = Lives + cond ' Score 999999 is the limit for PRINT USING FOR t = 1 TO 2 IF Player(t).Score > 999999 THEN Player(t).Score = 999999 NEXT t IF PlayrNum = 1 THEN ' One player game score format LOCATE 1, 1: PRINT USING "Score ###,###"; Player(1).Score LOCATE 1, 64: PRINT USING "Lives #"; Lives ELSE ' Two player game score format LOCATE 1, 1: PRINT Player(2).PlayrName; PRINT USING " - ###"; Player(2).Score LOCATE 1, 64: PRINT Player(1).PlayrName; PRINT USING " - ###"; Player(1).Score END IF END SUB ' End Scene ends the game and determines the winner SUB EndScene FuncKeyOff ' Draws the concecrated circles of the end scene Center 13, "The End" PLAY "T255L64O1" FOR y = 15 TO 0 STEP -15 FOR t = 50 TO 500 STEP 20 CIRCLE (320, 100), t, y, , , .25 IF SoundOn THEN PLAY "a" NEXT t NEXT y PLAY "T160L4" SLEEP 2 SCREEN 0: CLS : COLOR 15, 0 IF PlayrNum = 2 THEN FOR t = 1 TO 2 COLOR 4, 0 Center ((t - 1) * 5 + 5), "Player 1 -- " + Player(t).PlayrName Center ((t - 1) * 5 + 6), "Score -" + STR$(Player(t).Score) NEXT t COLOR 14, 0 Center 13, "The Winner is:" COLOR 15, 0 IF Player(1).Score < Player(2).Score THEN Center 15, Player(2).PlayrName ELSE Center 15, Player(1).PlayrName END IF ELSE PLAY "T255L64O4" Center 8, "Lives X Hits X 10 = Bonus" COLOR 11, 0 Center 10, STR$(Lives) + " X" + STR$(NumbrHits) + " =" + STR$(Lives * NumbrHits) + " X 10" FOR t = 1 TO Lives * NumbrHits DsplyScore 10, 0, 0 IF SoundOn THEN PLAY "a" NEXT t COLOR 14, 0 Center 13, "Total score" + STR$(Player(1).Score) Center 14, "The End" END IF END SUB ' Explode is self explanatory SUB Explode (p1, p2) ' Sound effect IF SoundOn THEN PLAY "MBO0L16efgefedc" ' Draw explosion FOR i# = 2 TO 1 STEP -1 FOR y = 1 TO 50 STEP i# CIRCLE (p1 + 20, p2 + 15), y, (i# - 1) * 4 FOR z = 1 TO 500: NEXT z NEXT y NEXT i# END SUB ' FindShip determines which ship to blow up. SUB FindShip FOR t = 1 TO 2 IF NOT (Player(t).Alive) THEN Explode Player(t).HorizPos, Player(t).VertPos TallyScore t Player(t).HorizPos = (t AND 1) * 599 Player(t).VertPos = 100 Player(t).Alive = TRUE END IF NEXT t END SUB ' FireBullet is self explanatory SUB FireBullet (Num) ' Position bullet Player(Num).ShotHoriz = Player(Num).HorizPos + ((Num - 1) * 40) Player(Num).ShotVert = Player(Num).VertPos + 15 ' Make sound effect IF SoundOn THEN PLAY "MBO" + STR$(Num + 3) + "L64bagfedcbagfedcL4" ' Make bullet active Player(Num).Shot = TRUE END SUB ' FuncKeyDisplay displays the active function key and their effects. SUB FuncKeyDisplay LOCATE 3, 1 PRINT "[F1] -- Help", "[F2] -- Hide", OnOff "[F3] -- Sound", SoundOn PRINT " [F4] -- Pause [F5] -- Quit " END SUB ' FuncKeyOff turns all the key traps off. SUB FuncKeyOff FOR Func = 1 TO 5 KEY(t) OFF NEXT Func END SUB ' FuncKeyOn turns all the key traps on. SUB FuncKeyOn FOR Func = 1 TO 5 KEY(t) ON NEXT Func END SUB SUB GameSetUp COLOR 15, 0: CLS : LOCATE 5, 1 PRINT "Press [1] or [2] players" DO: a$ = INPUT$(1): LOOP WHILE a$ < "1" OR a$ > "2" PlayrNum = VAL(a$) ' Set up beginning coordinates and direction FOR t = 1 TO 2 Player(t).HorizPos = (t AND 1) * 599: Player(t).VertPos = 100 Player(t).HorizDir = (t - 1) * (PlayrNum AND 1) * 4 Player(t).VertDir = (t - 1) * (PlayrNum AND 1) * 4 Player(t).Score = 0: Player(t).Alive = TRUE Player(t).ShotHoriz = ((t XOR 1) AND 1) * 641 - 1 Player(t).Shot = FALSE Player(t).Joystick = FALSE NEXT t FOR t = 1 TO PlayrNum PRINT : PRINT "Enter name player"; t LINE INPUT Player(t).PlayrName IF Player(t).PlayrName = SPACE$(10) THEN Player(t).PlayrName = "Player" + STR$(t) END IF IF JoyFlag THEN PRINT "Do you want to use joystick"; IF Yes THEN Player(t).Joystick = TRUE PRINT : PRINT "Press [ESC] to exit" PRINT "Move joystick to upper left, and press fire: "; DO IF INKEY$ = CHR$(27) THEN Player(t).Joystick = FALSE: EXIT DO ' Get current minimum joystick coordinates Joystick(t * 2 - 2).Min = STICK(t * 2 - 2) + 10 Joystick(t * 2 - 1).Min = STICK(t * 2 - 1) + 10 LOOP UNTIL STRIG(t * 2 - 1) OR STRIG(t * 2 + 3) PRINT "OK" PRINT "Move joystick to lower right, and press fire: "; WHILE STRIG(t * 2 - 1) OR STRIG(t * 2 + 3): WEND DO IF INKEY$ = CHR$(27) THEN Player(t).Joystick = FALSE: EXIT DO ' Get current maximum joystick coordinates Joystick(t * 2 - 2).Max = STICK(t * 2 - 2) - 10 Joystick(t * 2 - 1).Max = STICK(t * 2 - 1) - 10 LOOP UNTIL STRIG(t * 2 - 1) OR STRIG(t * 2 + 3) PRINT "OK" END IF END IF NEXT t MachSpeed = CalcDelay Lives = 5: NumbrHits = 0: Time = 255 Astrd.Smash = FALSE: Astrd.TorF = FALSE: Astrd.Shot = FALSE END SUB SUB GetDirections a$ = UCASE$(INKEY$) ' Get joystick direction, if player is using joystick IF Player(1).Joystick THEN SELECT CASE STICK(0) CASE IS < Joystick(0).Min: Player(1).HorizDir = -4 CASE IS > Joystick(0).Max: Player(1).HorizDir = 4 CASE ELSE: Player(1).HorizDir = 0 END SELECT SELECT CASE STICK(1) CASE IS < Joystick(1).Min: Player(1).VertDir = -4 CASE IS > Joystick(1).Max: Player(1).VertDir = 4 CASE ELSE: Player(1).VertDir = 0 END SELECT IF STRIG(0) OR STRIG(4) THEN FireBullet 1 ELSE ' Get direction from keyboard, if player is using keyboard SELECT CASE a$ CASE CHR$(0) + "H": Player(1).VertDir = -4: Player(1).HorizDir = 0 CASE CHR$(0) + "K": Player(1).HorizDir = -4: Player(1).VertDir = 0 CASE CHR$(0) + "P": Player(1).VertDir = 4: Player(1).HorizDir = 0 CASE CHR$(0) + "M": Player(1).HorizDir = 4: Player(1).VertDir = 0 CASE " " Player(1).ShotHoriz = Player(1).HorizPos Player(1).ShotVert = Player(1).VertPos + 15 IF SoundOn THEN PLAY "MBO4L64bagfedcbagfedcL4" Player(1).Shot = TRUE END SELECT END IF IF PlayrNum = 2 THEN ' Get joystick direction, if player is using joystick IF Player(2).Joystick THEN SELECT CASE STICK(2) CASE IS < Joystick(2).Min: Player(2).HorizDir = -4 CASE IS > Joystick(2).Max: Player(2).HorizDir = 4 CASE ELSE: Player(2).HorizDir = 0 END SELECT SELECT CASE STICK(3) CASE IS < Joystick(3).Min: Player(2).VertDir = -4 CASE IS > Joystick(3).Max: Player(2).VertDir = 4 CASE ELSE: Player(2).VertDir = 0 END SELECT IF STRIG(2) OR STRIG(6) THEN FireBullet 2 ELSE ' Get direction from keyboard, if player is using keyboard SELECT CASE a$ CASE "W": Player(2).VertDir = -4: Player(2).HorizDir = 0 CASE "A": Player(2).HorizDir = -4: Player(2).VertDir = 0 CASE "S": Player(2).VertDir = 4: Player(2).HorizDir = 0 CASE "D": Player(2).HorizDir = 4: Player(2).VertDir = 0 CASE CHR$(27) Player(2).ShotHoriz = Player(2).HorizPos + 40 Player(2).ShotVert = Player(2).VertPos + 15 IF SoundOn THEN PLAY "MBO5L64bagfedcbagfedcL4" Player(2).Shot = TRUE END SELECT END IF END IF END SUB SUB Initialize SCREEN 0: COLOR 15, 0 KEY OFF FOR t = 1 TO 5: KEY t, "": NEXT t IF UCASE$(COMMAND$) <> "-S" THEN SoundOn = TRUE ELSE SoundOn = FALSE END IF ON KEY(1) GOSUB HelpScreen ON KEY(2) GOSUB DosHide ON KEY(3) GOSUB SoundToggle ON KEY(4) GOSUB Pause ON KEY(5) GOSUB Quit ' This is a clever method to detect whether the system ' supports joysticks. JoyFlag = TRUE ON ERROR GOTO StickError a = STICK(0): ON ERROR GOTO 0 END SUB ' Reinitialize Graphics Mode 2 SUB InitPlayArea ON ERROR GOTO GraphicsError SCREEN 2: ON ERROR GOTO 0 Center 11, "Initializing playfield" ' Draw 300 stars FOR t = 1 TO 300: PSET (RND * 640, RND * 200): NEXT t ' Draw line separator LINE (0, 28)-(640, 28) Center 11, SPACE$(21) TimeDsply 0 DsplyScore 0, 0, 0 FuncKeyDisplay PUT (Player(1).HorizPos, Player(1).VertPos), OnePlayr%, PSET ' Put both players PUT (Player(2).HorizPos, Player(2).VertPos), TwoPlayr%, PSET ' on screen Center 11, "Press any key when ready" KeyPause Center 11, SPACE$(24) END SUB ' KeyPause is self explanatory SUB KeyPause WHILE INKEY$ <> "": WEND ' Clear keyboard WHILE INKEY$ = "": WEND ' Wait for key END SUB SUB MoveAstrd ' Exit if Asteroid does not exist IF NOT (Astrd.TorF) THEN EXIT SUB Astrd.Horiz = Astrd.Horiz + Astrd.DirHoriz Astrd.Vert = Astrd.Vert + Astrd.DirVert ' Check to see if either ship shot asteroid FOR t = 1 TO 2 IF Player(t).Shot THEN IF Astrd.Horiz + 40 < Player(t).ShotHoriz THEN GOTO missastrd IF Astrd.Horiz > Player(t).ShotHoriz THEN GOTO missastrd IF Astrd.Vert + 30 < Player(t).ShotVert THEN GOTO missastrd IF Astrd.Vert > Player(t).ShotVert THEN GOTO missastrd Astrd.Shot = TRUE: Astrd.TorF = FALSE: Player(t).Shot = FALSE missastrd: END IF NEXT t ' Remove asteroid if it goes out of bounds IF Astrd.Horiz < leftbound OR Astrd.Horiz > rightbound THEN Astrd.TorF = FALSE: Astrd.Horiz = Astrd.Horiz - Astrd.DirHoriz END IF IF Astrd.Vert < upbound OR Astrd.Vert > downbound THEN Astrd.TorF = FALSE: Astrd.Vert = Astrd.Vert - Astrd.DirVert END IF IF Astrd.TorF THEN PUT (Astrd.Horiz, Astrd.Vert), Asteroid%, PSET ELSE LINE (Astrd.Horiz, Astrd.Vert)-(Astrd.Horiz + 40, Astrd.Vert + 30), 0, BF END IF END SUB SUB MoveBullets FOR t = 1 TO 2 ' Move player's bullet, only when it's active. IF Player(t).Shot THEN ' Erase bullet LOCATE Player(t).ShotVert / 8 + 1, Player(t).ShotHoriz / 8 + 1 PRINT " "; ' Move bullet IF t = 1 THEN Player(1).ShotHoriz = Player(1).ShotHoriz - 8 ELSE Player(2).ShotHoriz = Player(2).ShotHoriz + 8 END IF ELSE ' If computer's bullet inactive, have computer refire the bullet. IF PlayrNum = 1 AND t = 2 THEN Player(2).ShotHoriz = Player(2).HorizPos + 40 Player(2).ShotVert = Player(2).VertPos + 15 Player(2).Shot = TRUE END IF END IF ' If bullet goes out of bounds, make bullet inactive. IF t = 1 THEN IF Player(1).ShotHoriz < 0 THEN Player(1).Shot = FALSE ELSE IF Player(2).ShotHoriz > 639 THEN Player(2).Shot = FALSE END IF ' Plot the shot of the active bullet. IF Player(t).Shot THEN LOCATE Player(t).ShotVert / 8 + 1, Player(t).ShotHoriz / 8 + 1 PRINT "*"; END IF NEXT t END SUB ' Moves both the ships on the screen SUB MoveShips ' This FOR..NEXT loop moves boths ships and keeps them inbounds FOR t = 1 TO 2 Player(t).HorizPos = Player(t).HorizPos + Player(t).HorizDir IF Player(t).HorizPos < leftbound THEN Player(t).HorizPos = leftbound IF Player(t).HorizPos > rightbound THEN Player(t).HorizPos = rightbound Player(t).VertPos = Player(t).VertPos + Player(t).VertDir IF Player(t).VertPos < upbound THEN Player(t).VertPos = upbound IF Player(t).VertPos > downbound THEN Player(t).VertPos = downbound NEXT t ' If a one player game, computer determines next move when computer's ' ship reaches the boundaries. IF PlayrNum = 1 THEN IF Player(2).HorizPos < leftbound + 4 OR Player(2).HorizPos > rightbound - 4 THEN Player(2).HorizDir = -(Player(2).HorizDir) END IF IF Player(2).VertPos < upbound + 4 OR Player(2).VertPos > downbound - 4 THEN Player(2).VertDir = -(Player(2).VertDir) END IF END IF ' Redraw the ships in new coordinates PUT (Player(1).HorizPos, Player(1).VertPos), OnePlayr%, PSET PUT (Player(2).HorizPos, Player(2).VertPos), TwoPlayr%, PSET END SUB SUB ObjectScreen COLOR 15, 0 'Restore text and set foreground color to white CLS : Center 3, "Space War!" Center 4, "1987..1993 by Gary N. Wilkerson Jr." COLOR 14, 0: Center 6, "One Player Game" COLOR 11, 0: Center 8, "Shoot the enemy as many times as possible" Center 9, "before time expires." Center 10, "When time expires, you get bonus for" Center 11, "the number of times you hit the enemy" Center 12, "multiplied by the number of remaining lives times ten." COLOR 13, 0: Center 14, "Two Player Game" COLOR 11, 0: Center 16, "Two players battle it out until times runs out." Center 17, "The player with the most points, wins!!!" COLOR 15, 0: Center 19, "Press any key to continue" SparklePause END SUB ' OnOff displays [ON] if condition (cond) is TRUE ' otherwise it displays [OFF]. SUB OnOff (text$, cond) PRINT text$; " "; IF cond THEN PRINT "[ON]"; ELSE PRINT ; "[OFF]"; END SUB SUB PlaySpWar Clock = 0 DO WHILE Time > 0 OR (PlayrNum = 2 AND Player(1).Score = Player(2).Score) GetDirections MoveShips MoveBullets MoveAstrd PSET (RND * 640, 20 + RND * 180) 'Restore a star IF ShipShot THEN FindShip IF Astrd.Shot OR Astrd.Smash THEN Explode INT(Astrd.Horiz), INT(Astrd.Vert) IF NOT (Astrd.Smash) THEN TimeDsply 15 Astrd.Shot = FALSE: Astrd.Smash = FALSE END IF ' Delay Game Rest .005 ' End game if Player 1 runs out of lives IF PlayrNum = 1 AND Lives < 1 THEN Time = 0: EXIT SUB Clock = Clock + 1 AND 255 IF Clock = 0 AND Astrd.TorF = FALSE THEN Astrd.TorF = TRUE: Astrd.Smash = FALSE: Astrd.Shot = FALSE Astrd.Horiz = RND * 640: Astrd.DirHoriz = RND * 4 ' Use the random event generator to determine asteroid's direction IF RND * 2 >= 1 THEN Astrd.DirHoriz = -Astrd.DirHoriz IF RND * 2 >= 1 THEN Astrd.Vert = upbound: Astrd.DirVert = RND * 4 ELSE Astrd.Vert = downbound: Astrd.DirVert = -RND * 4 END IF IF SoundOn THEN PLAY "MBO0L16>ccce" END IF IF (Clock AND 15) = 0 THEN TimeDsply -1 LOOP END SUB 'Rest: ' pauses the program SUB Rest (t#) s# = TIMER t2# = MachSpeed * t# / SPEEDCONST DO LOOP UNTIL TIMER - s# > t2# END SUB ' This procedure checks to see if either ship has crashed ' The GOTO's were necessary I'm afraid in order to make the game run faster ' by not testing all the conditions unless a ship has crashed in any way. FUNCTION ShipShot ShipShot = FALSE ' Check if bullet hit ships FOR t = 1 TO 2 IF Player(t XOR 3).Shot THEN IF Player(t).HorizPos > Player(t XOR 3).ShotHoriz THEN GOTO missed IF Player(t).HorizPos + 40 < Player(t XOR 3).ShotHoriz THEN GOTO missed IF Player(t).VertPos > Player(t XOR 3).ShotVert THEN GOTO missed IF Player(t).VertPos + 30 < Player(t XOR 3).ShotVert THEN GOTO missed Player(t).Alive = FALSE: ShipShot = TRUE Player(t XOR 3).Shot = FALSE missed: END IF NEXT t 'Check if ships hit each other IF Player(1).HorizPos < Player(2).HorizPos - 20 THEN GOTO safe IF Player(1).HorizPos > Player(2).HorizPos + 20 THEN GOTO safe IF Player(1).VertPos < Player(2).VertPos - 15 THEN GOTO safe IF Player(1).VertPos > Player(2).VertPos + 15 THEN GOTO safe FOR t = 1 TO 2: Player(t).Alive = FALSE: NEXT t: ShipShot = TRUE safe: ' Check if ships hit asteroid FOR t = 1 TO 2 IF Astrd.TorF THEN IF Player(t).HorizPos < Astrd.Horiz - 20 THEN GOTO clr IF Player(t).HorizPos > Astrd.Horiz + 20 THEN GOTO clr IF Player(t).VertPos < Astrd.Vert - 15 THEN GOTO clr IF Player(t).VertPos > Astrd.Vert + 15 THEN GOTO clr Astrd.TorF = FALSE: Astrd.Smash = TRUE ShipShot = TRUE: Player(t).Alive = FALSE clr: END IF NEXT t END FUNCTION ' Sparklepause creates a flashing border for intro scenes SUB SparklePause a$ = "* * * * * * * * * * * * * * * * * " WHILE INKEY$ <> "": WEND WHILE INKEY$ = "" COLOR VAL(RIGHT$(TIME$, 2)) AND 15, 0 FOR t = 1 TO 5 LOCATE 1, 1: PRINT MID$(a$, t, 80); LOCATE 22, 1: PRINT MID$(a$, 6 - t, 80); FOR x = 2 TO 21 y = (t + x) MOD 5 IF y = 1 THEN b$ = "*" ELSE b$ = " " LOCATE x, 80: PRINT b$; LOCATE 23 - x, 1: PRINT b$; NEXT x NEXT t WEND COLOR 15, 0 END SUB SUB TallyScore (Playr) ' Tally score according number of players IF PlayrNum = 1 THEN ' One Player game IF Playr = 1 THEN ' Player got shot DsplyScore 0, 0, -1 ELSE ' Computer got shot ' Determine Score& by distance between ships y = Player(1).HorizPos - Player(2).HorizPos IF y >= 240 THEN Score& = 700 ' Long distance, sharp shooter ELSEIF y >= 140 AND y < 240 THEN Score& = 300 ' Safe distance, wimp ELSEIF y >= 90 AND y < 140 THEN Score& = 600 ' Moderate distance ELSEIF y >= 0 AND y < 90 THEN Score& = 900 ' Point blank, LOOKOUT!!! ELSE Score& = 100 ' Playing chicken, aren't we? END IF ' Display bonus score LOCATE Player(2).VertPos / 8 + 1, Player(2).HorizPos / 8 + 1 PRINT Score&; : SLEEP 1 LOCATE Player(2).VertPos / 8 + 1, Player(2).HorizPos / 8 + 1 PRINT SPACE$(4); DsplyScore Score&, 0, 0 NumbrHits = NumbrHits + 1 END IF ELSE ' Two Player game IF Playr = 1 THEN DsplyScore 0, 1, 0 ELSE DsplyScore 1, 0, 0 END IF END SUB ' This SUB module adds assigned value to the time and displays it SUB TimeDsply (cond) Time = Time + cond IF Time < 0 THEN EXIT SUB LOCATE 2, 32 PRINT USING "Time ##:##"; INT(Time / 60); Time MOD 60 END SUB FUNCTION Yes PRINT " (y/n)?"; DO: a$ = UCASE$(INPUT$(1)) LOOP UNTIL a$ = "Y" OR a$ = "N" IF a$ = "Y" THEN Yes = TRUE ELSE Yes = FALSE END FUNCTION