' Q B a s i c G o r i l l a s ' ' Copyright (C) Microsoft Corporation 1990 ' ' Your mission is to hit your opponent with the exploding banana ' by varying the angle and power of your throw, taking into account ' wind speed, gravity, and the city skyline. ' ' Speed of this game is determined by the constant SPEEDCONST. If the ' program is too slow or too fast adjust the "CONST SPEEDCONST = 500" line ' below. The larger the number the faster the game will go. ' ' To run this game, press Shift+F5. ' ' To exit QBasic, press Alt, F, X. ' ' To get help on a BASIC keyword, move the cursor to the keyword and press ' F1 or click the right mouse button. ' 'Set default data type to integer for faster game play DEFINT A-Z 'Sub Declarations DECLARE SUB DoSun (Mouth) DECLARE SUB SetScreen () DECLARE SUB EndGame () DECLARE SUB Center (Row, Text$) DECLARE SUB Intro () DECLARE SUB SparklePause () DECLARE SUB GetInputs (Player1$, Player2$, NumGames) DECLARE SUB PlayGame (Player1$, Player2$, NumGames) DECLARE SUB DoExplosion (x#, y#) DECLARE SUB MakeCityScape (BCoor() AS ANY) DECLARE SUB PlaceGorillas (BCoor() AS ANY) DECLARE SUB UpdateScores (Record(), PlayerNum, Results) DECLARE SUB DrawGorilla (x, y, arms) DECLARE SUB GorillaIntro (Player1$, Player2$) DECLARE SUB Rest (t#) DECLARE SUB VictoryDance (Player) DECLARE SUB ClearGorillas () DECLARE SUB DrawBan (xc#, yc#, r, bc) DECLARE FUNCTION Scl (n!) DECLARE FUNCTION GetNum# (Row, Col) DECLARE FUNCTION DoShot (PlayerNum, x, y) DECLARE FUNCTION ExplodeGorilla (x#, y#) DECLARE FUNCTION Getn# (Row, Col) DECLARE FUNCTION PlotShot (StartX, StartY, Angle#, Velocity, PlayerNum) DECLARE FUNCTION CalcDelay! () 'Make all arrays Dynamic '$DYNAMIC 'User-Defined TYPEs TYPE XYPoint XCoor AS INTEGER YCoor AS INTEGER END TYPE 'Constants CONST SPEEDCONST = 500 CONST TRUE = -1 CONST FALSE = NOT TRUE CONST HITSELF = 1 CONST BACKATTR = 0 CONST OBJECTCOLOR = 1 CONST WINDOWCOLOR = 14 CONST SUNATTR = 3 CONST SUNHAPPY = FALSE CONST SUNSHOCK = TRUE CONST RIGHTUP = 1 CONST LEFTUP = 2 CONST ARMSDOWN = 3 STOP END Player1$, Player2$ - player names ' NumGames - number of games to play SUB PlayGame (Player1$, Player2$, NumGames) DIM BCoor(0 TO 30) AS XYPoint DIM TotalWins(1 TO 2) J = 1 FOR i = 1 TO NumGames CLS RANDOMIZE (TIMER) CALL MakeCityScape(BCoor()) CALL PlaceGorillas(BCoor()) DoSun SUNHAPPY Hit = FALSE DO WHILE Hit = FALSE J = 1 - J LOCATE 1, 1 PRINT Player1$ LOCATE 1, (MaxCol - 1 - LEN(Player2$)) PRINT Player2$ Center 23, LTRIM$(STR$(TotalWins(1))) + ">Score<" + LTRIM$(STR$(TotalWins(2))) Tosser = J + 1: Tossee = 3 - J 'Plot the shot. Hit is true if Gorilla gets hit. Hit = DoShot(Tosser, GorillaX(Tosser), GorillaY(Tosser)) 'Reset the sun, if it got hit IF SunHit THEN DoSun SUNHAPPY IF Hit = TRUE THEN CALL UpdateScores(TotalWins(), Tosser, Hit) LOOP SLEEP 1 NEXT i SCREEN 0 WIDTH 80, 25 COLOR 7, 0 MaxCol = 80 CLS Center 8, "GAME OVER!" Center 10, "Score:" LOCATE 11, 30: PRINT Player1$; TAB(50); TotalWins(1) LOCATE 12, 30: PRINT Player2$; TAB(50); TotalWins(2) Center 24, "Press any key to continue" SparklePause COLOR 7, 0 CLS END SUB 'PlayGame: ' Plots banana shot across the screen 'Parameters: ' StartX, StartY - starting shot location ' Angle - shot angle ' Velocity - shot velocity ' PlayerNum - the banana thrower FUNCTION PlotShot (StartX, StartY, Angle#, Velocity, PlayerNum) Angle# = Angle# / 180 * pi# 'Convert degree angle to radians Radius = Mode MOD 7 InitXVel# = COS(Angle#) * Velocity InitYVel# = SIN(Angle#) * Velocity oldx# = StartX oldy# = StartY 'draw gorilla toss IF PlayerNum = 1 THEN PUT (StartX, StartY), GorL&, PSET ELSE PUT (StartX, StartY), GorR&, PSET END IF 'throw sound PLAY "MBo0L32A-L64CL16BL64A+" Rest .1 'redraw gorilla PUT (StartX, StartY), GorD&, PSET adjust = Scl(4) 'For scaling CGA xedge = Scl(9) * (2 - PlayerNum) 'Find leading edge of banana for check Impact = FALSE ShotInSun = FALSE OnScreen = TRUE PlayerHit = 0 NeedErase = FALSE StartXPos = StartX StartYPos = StartY - adjust - 3 IF PlayerNum = 2 THEN StartXPos = StartXPos + Scl(25) direction = Scl(4) ELSE direction = Scl(-4) END IF IF Velocity < 2 THEN 'Shot too slow - hit self x# = StartX y# = StartY pointval = OBJECTCOLOR END IF DO WHILE (NOT Impact) AND OnScreen Rest .02 'Erase old banana, if necessary IF NeedErase THEN NeedErase = FALSE CALL DrawBan(oldx#, oldy#, oldrot, FALSE) END IF x# = StartXPos + (InitXVel# * t#) + (.5 * (Wind / 5) * t# ^ 2) y# = StartYPos + ((-1 * (InitYVel# * t#)) + (.5 * gravity# * t# ^ 2)) * (ScrHeight / 350) IF (x# >= ScrWidth - Scl(10)) OR (x# <= 3) OR (y# >= ScrHeight - 3) THEN OnScreen = FALSE END IF IF OnScreen AND y# > 0 THEN 'check it LookY = 0 LookX = Scl(8 * (2 - PlayerNum)) DO pointval = POINT(x# + LookX, y# + LookY) IF pointval = 0 THEN Impact = FALSE IF ShotInSun = TRUE THEN IF ABS(ScrWidth \ 2 - x#) > Scl(20) OR y# > SunHt THEN ShotInSun = FALSE END IF ELSEIF pointval = SUNATTR AND y# < SunHt THEN IF NOT SunHit THEN DoSun SUNSHOCK SunHit = TRUE ShotInSun = TRUE ELSE Impact = TRUE END IF LookX = LookX + direction LookY = LookY + Scl(6) LOOP UNTIL Impact OR LookX <> Scl(4) IF NOT ShotInSun AND NOT Impact THEN 'plot it rot = (t# * 10) MOD 4 CALL DrawBan(x#, y#, rot, TRUE) NeedErase = TRUE END IF oldx# = x# oldy# = y# oldrot = rot END IF t# = t# + .1 LOOP IF pointval <> OBJECTCOLOR AND Impact THEN CALL DoExplosion(x# + adjust, y# + adjust) ELSEIF pointval = OBJECTCOLOR THEN PlayerHit = ExplodeGorilla(x#, y#) END IF PlotShot = PlayerHit END FUNCTION 'Rest: ' pauses the program SUB Rest (t#) s# = TIMER t2# = MachSpeed * t# / SPEEDCONST DO LOOP UNTIL TIMER - s# > t2# END SUB 'Scl: ' Pass the number in to scaling for cga. If the number is a decimal, then we ' want to scale down for cga or scale up for ega. This allows a full range ' of numbers to be generated for scaling. ' (i.e. for 3 to get scaled to 1, pass in 2.9) FUNCTION Scl (n!) IF n! <> INT(n!) THEN IF Mode = 1 THEN n! = n! - 1 END IF IF Mode = 1 THEN Scl = CINT(n! / 2 + .1) ELSE Scl = CINT(n!) END IF END FUNCTION 'SetScreen: ' Sets the appropriate color statements SUB SetScreen IF Mode = 9 THEN ExplosionColor = 2 BackColor = 1 PALETTE 0, 1 PALETTE 1, 46 PALETTE 2, 44 PALETTE 3, 54 PALETTE 5, 7 PALETTE 6, 4 PALETTE 7, 3 PALETTE 9, 63 'Display Color ELSE ExplosionColor = 2 BackColor = 0 COLOR BackColor, 2 END IF END SUB 'SparklePause: ' Creates flashing border for intro and game over screens SUB SparklePause COLOR 4, 0 A$ = "* * * * * * * * * * * * * * * * * " WHILE INKEY$ <> "": WEND 'Clear keyboard buffer WHILE INKEY$ = "" FOR A = 1 TO 5 LOCATE 1, 1 'print horizontal sparkles PRINT MID$(A$, A, 80); LOCATE 22, 1 PRINT MID$(A$, 6 - A, 80); FOR b = 2 TO 21 'Print Vertical sparkles c = (A + b) MOD 5 IF c = 1 THEN LOCATE b, 80 PRINT "*"; LOCATE 23 - b, 1 PRINT "*"; ELSE LOCATE b, 80 PRINT " "; LOCATE 23 - b, 1 PRINT " "; END IF NEXT b NEXT A WEND END SUB 'UpdateScores: ' Updates players' scores 'Parameters: ' Record - players' scores ' PlayerNum - player ' Results - results of player's shot SUB UpdateScores (Record(), PlayerNum, Results) IF Results = HITSELF THEN Record(ABS(PlayerNum - 3)) = Record(ABS(PlayerNum - 3)) + 1 ELSE Record(PlayerNum) = Record(PlayerNum) + 1 END IF END SUB 'VictoryDance: ' gorilla dances after he has eliminated his opponent 'Parameters: ' Player - which gorilla is dancing SUB VictoryDance (Player) FOR i# = 1 TO 4 PUT (GorillaX(Player), GorillaY(Player)), GorL&, PSET PLAY "MFO0L32EFGEFDC" Rest .2 PUT (GorillaX(Player), GorillaY(Player)), GorR&, PSET PLAY "MFO0L32EFGEFDC" Rest .2 NEXT END SUB