1 ' Q B a s i c G o r i l l a s
3 ' Copyright (C) Microsoft Corporation 1990
5 ' Your mission is to hit your opponent with the exploding banana
6 ' by varying the angle and power of your throw, taking into account
7 ' wind speed, gravity, and the city skyline.
9 ' Speed of this game is determined by the constant SPEEDCONST. If the
10 ' program is too slow or too fast adjust the "CONST SPEEDCONST = 500" line
11 ' below. The larger the number the faster the game will go.
13 ' To run this game, press Shift+F5.
15 ' To exit QBasic, press Alt, F, X.
17 ' To get help on a BASIC keyword, move the cursor to the keyword and press
18 ' F1 or click the right mouse button.
21 'Set default data type to integer for faster game play
25 DECLARE SUB DoSun (Mouth)
26 DECLARE SUB SetScreen ()
27 DECLARE SUB EndGame ()
28 DECLARE SUB Center (Row, Text$)
30 DECLARE SUB SparklePause ()
31 DECLARE SUB GetInputs (Player1$, Player2$, NumGames)
32 DECLARE SUB PlayGame (Player1$, Player2$, NumGames)
33 DECLARE SUB DoExplosion (x#, y#)
34 DECLARE SUB MakeCityScape (BCoor() AS ANY)
35 DECLARE SUB PlaceGorillas (BCoor() AS ANY)
36 DECLARE SUB UpdateScores (Record(), PlayerNum, Results)
37 DECLARE SUB DrawGorilla (x, y, arms)
38 DECLARE SUB GorillaIntro (Player1$, Player2$)
40 DECLARE SUB VictoryDance (Player)
41 DECLARE SUB ClearGorillas ()
42 DECLARE SUB DrawBan (xc#, yc#, r, bc)
43 DECLARE FUNCTION Scl (n!)
44 DECLARE FUNCTION GetNum# (Row, Col)
45 DECLARE FUNCTION DoShot (PlayerNum, x, y)
46 DECLARE FUNCTION ExplodeGorilla (x#, y#)
47 DECLARE FUNCTION Getn# (Row, Col)
48 DECLARE FUNCTION PlotShot (StartX, StartY, Angle#, Velocity, PlayerNum)
49 DECLARE FUNCTION CalcDelay! ()
51 'Make all arrays Dynamic
61 CONST SPEEDCONST = 500
63 CONST FALSE = NOT TRUE
67 CONST WINDOWCOLOR = 14
69 CONST SUNHAPPY = FALSE
80 Player1$, Player2$ - player names
81 ' NumGames - number of games to play
82 SUB PlayGame (Player1$, Player2$, NumGames)
83 DIM BCoor(0 TO 30) AS XYPoint
92 CALL MakeCityScape(BCoor())
93 CALL PlaceGorillas(BCoor())
100 LOCATE 1, (MaxCol - 1 - LEN(Player2$))
102 Center 23, LTRIM$(STR$(TotalWins(1))) + ">Score<" + LTRIM$(STR$(TotalWins(2)))
103 Tosser = J + 1: Tossee = 3 - J
105 'Plot the shot. Hit is true if Gorilla gets hit.
106 Hit = DoShot(Tosser, GorillaX(Tosser), GorillaY(Tosser))
108 'Reset the sun, if it got hit
109 IF SunHit THEN DoSun SUNHAPPY
111 IF Hit = TRUE THEN CALL UpdateScores(TotalWins(), Tosser, Hit)
122 Center 8, "GAME OVER!"
124 LOCATE 11, 30: PRINT Player1$; TAB(50); TotalWins(1)
125 LOCATE 12, 30: PRINT Player2$; TAB(50); TotalWins(2)
126 Center 24, "Press any key to continue"
133 ' Plots banana shot across the screen
135 ' StartX, StartY - starting shot location
137 ' Velocity - shot velocity
138 ' PlayerNum - the banana thrower
139 FUNCTION PlotShot (StartX, StartY, Angle#, Velocity, PlayerNum)
141 Angle# = Angle# / 180 * pi# 'Convert degree angle to radians
144 InitXVel# = COS(Angle#) * Velocity
145 InitYVel# = SIN(Angle#) * Velocity
151 IF PlayerNum = 1 THEN
152 PUT (StartX, StartY), GorL&, PSET
154 PUT (StartX, StartY), GorR&, PSET
158 PLAY "MBo0L32A-L64CL16BL64A+"
162 PUT (StartX, StartY), GorD&, PSET
164 adjust = Scl(4) 'For scaling CGA
166 xedge = Scl(9) * (2 - PlayerNum) 'Find leading edge of banana for check
175 StartYPos = StartY - adjust - 3
177 IF PlayerNum = 2 THEN
178 StartXPos = StartXPos + Scl(25)
184 IF Velocity < 2 THEN 'Shot too slow - hit self
187 pointval = OBJECTCOLOR
190 DO WHILE (NOT Impact) AND OnScreen
194 'Erase old banana, if necessary
197 CALL DrawBan(oldx#, oldy#, oldrot, FALSE)
200 x# = StartXPos + (InitXVel# * t#) + (.5 * (Wind / 5) * t# ^ 2)
201 y# = StartYPos + ((-1 * (InitYVel# * t#)) + (.5 * gravity# * t# ^ 2)) * (ScrHeight / 350)
203 IF (x# >= ScrWidth - Scl(10)) OR (x# <= 3) OR (y# >= ScrHeight - 3) THEN
208 IF OnScreen AND y# > 0 THEN
212 LookX = Scl(8 * (2 - PlayerNum))
214 pointval = POINT(x# + LookX, y# + LookY)
217 IF ShotInSun = TRUE THEN
218 IF ABS(ScrWidth \ 2 - x#) > Scl(20) OR y# > SunHt THEN ShotInSun = FALSE
220 ELSEIF pointval = SUNATTR AND y# < SunHt THEN
221 IF NOT SunHit THEN DoSun SUNSHOCK
227 LookX = LookX + direction
228 LookY = LookY + Scl(6)
229 LOOP UNTIL Impact OR LookX <> Scl(4)
231 IF NOT ShotInSun AND NOT Impact THEN
233 rot = (t# * 10) MOD 4
234 CALL DrawBan(x#, y#, rot, TRUE)
249 IF pointval <> OBJECTCOLOR AND Impact THEN
250 CALL DoExplosion(x# + adjust, y# + adjust)
251 ELSEIF pointval = OBJECTCOLOR THEN
252 PlayerHit = ExplodeGorilla(x#, y#)
263 t2# = MachSpeed * t# / SPEEDCONST
265 LOOP UNTIL TIMER - s# > t2#
269 ' Pass the number in to scaling for cga. If the number is a decimal, then we
270 ' want to scale down for cga or scale up for ega. This allows a full range
271 ' of numbers to be generated for scaling.
272 ' (i.e. for 3 to get scaled to 1, pass in 2.9)
275 IF n! <> INT(n!) THEN
276 IF Mode = 1 THEN n! = n! - 1
279 Scl = CINT(n! / 2 + .1)
287 ' Sets the appropriate color statements
300 PALETTE 9, 63 'Display Color
311 ' Creates flashing border for intro and game over screens
315 A$ = "* * * * * * * * * * * * * * * * * "
316 WHILE INKEY$ <> "": WEND 'Clear keyboard buffer
320 LOCATE 1, 1 'print horizontal sparkles
321 PRINT MID$(A$, A, 80);
323 PRINT MID$(A$, 6 - A, 80);
325 FOR b = 2 TO 21 'Print Vertical sparkles
344 ' Updates players' scores
346 ' Record - players' scores
348 ' Results - results of player's shot
349 SUB UpdateScores (Record(), PlayerNum, Results)
350 IF Results = HITSELF THEN
351 Record(ABS(PlayerNum - 3)) = Record(ABS(PlayerNum - 3)) + 1
353 Record(PlayerNum) = Record(PlayerNum) + 1
358 ' gorilla dances after he has eliminated his opponent
360 ' Player - which gorilla is dancing
361 SUB VictoryDance (Player)
364 PUT (GorillaX(Player), GorillaY(Player)), GorL&, PSET
365 PLAY "MFO0L32EFGEFDC"
367 PUT (GorillaX(Player), GorillaY(Player)), GorR&, PSET
368 PLAY "MFO0L32EFGEFDC"