X-Git-Url: http://git.harvie.cz/?a=blobdiff_plain;ds=sidebyside;f=turbobasic%2F1998%2F3RD-PA.RTY%2FQBASIC%2FGORILLA.BAS;fp=turbobasic%2F1998%2F3RD-PA.RTY%2FQBASIC%2FGORILLA.BAS;h=4948055aaabb5894de376b4e3bbfc1ca4d5071ec;hb=8986c5cdb1ca4cb8b60d62cdf942eb84e8fe339b;hp=0000000000000000000000000000000000000000;hpb=ecef903d8113af5d734957400a4e90914bbe816e;p=mirrors%2FPrograms.git diff --git a/turbobasic/1998/3RD-PA.RTY/QBASIC/GORILLA.BAS b/turbobasic/1998/3RD-PA.RTY/QBASIC/GORILLA.BAS new file mode 100755 index 0000000..4948055 --- /dev/null +++ b/turbobasic/1998/3RD-PA.RTY/QBASIC/GORILLA.BAS @@ -0,0 +1,1135 @@ +' 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 + +'Global Variables +DIM SHARED GorillaX(1 TO 2) 'Location of the two gorillas +DIM SHARED GorillaY(1 TO 2) +DIM SHARED LastBuilding + +DIM SHARED pi# +DIM SHARED LBan&(x), RBan&(x), UBan&(x), DBan&(x) 'Graphical picture of banana +DIM SHARED GorD&(120) 'Graphical picture of Gorilla arms down +DIM SHARED GorL&(120) 'Gorilla left arm raised +DIM SHARED GorR&(120) 'Gorilla right arm raised + +DIM SHARED gravity# +DIM SHARED Wind + +'Screen Mode Variables +DIM SHARED ScrHeight +DIM SHARED ScrWidth +DIM SHARED Mode +DIM SHARED MaxCol + +'Screen Color Variables +DIM SHARED ExplosionColor +DIM SHARED SunColor +DIM SHARED BackColor +DIM SHARED SunHit + +DIM SHARED SunHt +DIM SHARED GHeight +DIM SHARED MachSpeed AS SINGLE + + DEF FnRan (x) = INT(RND(1) * x) + 1 + DEF SEG = 0 ' Set NumLock to ON + KeyFlags = PEEK(1047) + IF (KeyFlags AND 32) = 0 THEN + POKE 1047, KeyFlags OR 32 + END IF + DEF SEG + + GOSUB InitVars + Intro + GetInputs Name1$, Name2$, NumGames + GorillaIntro Name1$, Name2$ + PlayGame Name1$, Name2$, NumGames + + DEF SEG = 0 ' Restore NumLock state + POKE 1047, KeyFlags + DEF SEG +END + + +CGABanana: + 'BananaLeft + DATA 327686, -252645316, 60 + 'BananaDown + DATA 196618, -1057030081, 49344 + 'BananaUp + DATA 196618, -1056980800, 63 + 'BananaRight + DATA 327686, 1010580720, 240 + +EGABanana: + 'BananaLeft + DATA 458758,202116096,471604224,943208448,943208448,943208448,471604224,202116096,0 + 'BananaDown + DATA 262153, -2134835200, -2134802239, -2130771968, -2130738945,8323072, 8323199, 4063232, 4063294 + 'BananaUp + DATA 262153, 4063232, 4063294, 8323072, 8323199, -2130771968, -2130738945, -2134835200,-2134802239 + 'BananaRight + DATA 458758, -1061109760, -522133504, 1886416896, 1886416896, 1886416896,-522133504,-1061109760,0 + +InitVars: + pi# = 4 * ATN(1#) + + 'This is a clever way to pick the best graphics mode available + ON ERROR GOTO ScreenModeError + Mode = 9 + SCREEN Mode + ON ERROR GOTO PaletteError + IF Mode = 9 THEN PALETTE 4, 0 'Check for 64K EGA + ON ERROR GOTO 0 + + MachSpeed = CalcDelay + + IF Mode = 9 THEN + ScrWidth = 640 + ScrHeight = 350 + GHeight = 25 + RESTORE EGABanana + REDIM LBan&(8), RBan&(8), UBan&(8), DBan&(8) + + FOR i = 0 TO 8 + READ LBan&(i) + NEXT i + + FOR i = 0 TO 8 + READ DBan&(i) + NEXT i + + FOR i = 0 TO 8 + READ UBan&(i) + NEXT i + + FOR i = 0 TO 8 + READ RBan&(i) + NEXT i + + SunHt = 39 + + ELSE + + ScrWidth = 320 + ScrHeight = 200 + GHeight = 12 + RESTORE CGABanana + REDIM LBan&(2), RBan&(2), UBan&(2), DBan&(2) + REDIM GorL&(20), GorD&(20), GorR&(20) + + FOR i = 0 TO 2 + READ LBan&(i) + NEXT i + FOR i = 0 TO 2 + READ DBan&(i) + NEXT i + FOR i = 0 TO 2 + READ UBan&(i) + NEXT i + FOR i = 0 TO 2 + READ RBan&(i) + NEXT i + + MachSpeed = MachSpeed * 1.3 + SunHt = 20 + END IF +RETURN + +ScreenModeError: + IF Mode = 1 THEN + CLS + LOCATE 10, 5 + PRINT "Sorry, you must have CGA, EGA color, or VGA graphics to play GORILLA.BAS" + END + ELSE + Mode = 1 + RESUME + END IF + +PaletteError: + Mode = 1 '64K EGA cards will run in CGA mode. + RESUME NEXT + +REM $STATIC +'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 and prints a text string on a given row +' Parameters: +' Row - screen row number +' Text$ - text to be printed +' +SUB Center (Row, Text$) + Col = MaxCol \ 2 + LOCATE Row, Col - (LEN(Text$) / 2 + .5) + PRINT Text$; +END SUB + +' DoExplosion: +' Produces explosion when a shot is fired +' Parameters: +' X#, Y# - location of explosion +' +SUB DoExplosion (x#, y#) + + PLAY "MBO0L32EFGEFDC" + Radius = ScrHeight / 50 + IF Mode = 9 THEN Inc# = .5 ELSE Inc# = .41 + FOR c# = 0 TO Radius STEP Inc# + CIRCLE (x#, y#), c#, ExplosionColor + NEXT c# + FOR c# = Radius TO 0 STEP (-1 * Inc#) + CIRCLE (x#, y#), c#, BACKATTR + FOR i = 1 TO 100 + NEXT i + Rest .005 + NEXT c# +END SUB + +' DoShot: +' Controls banana shots by accepting player input and plotting +' shot angle +' Parameters: +' PlayerNum - Player +' x, y - Player's gorilla position +' +FUNCTION DoShot (PlayerNum, x, y) + + 'Input shot + IF PlayerNum = 1 THEN + LocateCol = 1 + ELSE + IF Mode = 9 THEN + LocateCol = 66 + ELSE + LocateCol = 26 + END IF + END IF + + LOCATE 2, LocateCol + PRINT "Angle:"; + Angle# = GetNum#(2, LocateCol + 7) + + LOCATE 3, LocateCol + PRINT "Velocity:"; + Velocity = GetNum#(3, LocateCol + 10) + + IF PlayerNum = 2 THEN + Angle# = 180 - Angle# + END IF + + 'Erase input + FOR i = 1 TO 4 + LOCATE i, 1 + PRINT SPACE$(30 \ (80 \ MaxCol)); + LOCATE i, (50 \ (80 \ MaxCol)) + PRINT SPACE$(30 \ (80 \ MaxCol)); + NEXT + + SunHit = FALSE + PlayerHit = PlotShot(x, y, Angle#, Velocity, PlayerNum) + IF PlayerHit = 0 THEN + DoShot = FALSE + ELSE + DoShot = TRUE + IF PlayerHit = PlayerNum THEN PlayerNum = 3 - PlayerNum + VictoryDance PlayerNum + END IF + +END FUNCTION + +' DoSun: +' Draws the sun at the top of the screen. +' Parameters: +' Mouth - If TRUE draws "O" mouth else draws a smile mouth. +' +SUB DoSun (Mouth) + + 'set position of sun + x = ScrWidth \ 2: y = Scl(25) + + 'clear old sun + LINE (x - Scl(22), y - Scl(18))-(x + Scl(22), y + Scl(18)), BACKATTR, BF + + 'draw new sun: + 'body + CIRCLE (x, y), Scl(12), SUNATTR + PAINT (x, y), SUNATTR + + 'rays + LINE (x - Scl(20), y)-(x + Scl(20), y), SUNATTR + LINE (x, y - Scl(15))-(x, y + Scl(15)), SUNATTR + + LINE (x - Scl(15), y - Scl(10))-(x + Scl(15), y + Scl(10)), SUNATTR + LINE (x - Scl(15), y + Scl(10))-(x + Scl(15), y - Scl(10)), SUNATTR + + LINE (x - Scl(8), y - Scl(13))-(x + Scl(8), y + Scl(13)), SUNATTR + LINE (x - Scl(8), y + Scl(13))-(x + Scl(8), y - Scl(13)), SUNATTR + + LINE (x - Scl(18), y - Scl(5))-(x + Scl(18), y + Scl(5)), SUNATTR + LINE (x - Scl(18), y + Scl(5))-(x + Scl(18), y - Scl(5)), SUNATTR + + 'mouth + IF Mouth THEN 'draw "o" mouth + CIRCLE (x, y + Scl(5)), Scl(2.9), 0 + PAINT (x, y + Scl(5)), 0, 0 + ELSE 'draw smile + CIRCLE (x, y), Scl(8), 0, (210 * pi# / 180), (330 * pi# / 180) + END IF + + 'eyes + CIRCLE (x - 3, y - 2), 1, 0 + CIRCLE (x + 3, y - 2), 1, 0 + PSET (x - 3, y - 2), 0 + PSET (x + 3, y - 2), 0 + +END SUB + +'DrawBan: +' Draws the banana +'Parameters: +' xc# - Horizontal Coordinate +' yc# - Vertical Coordinate +' r - rotation position (0-3). ( \_/ ) /-\ +' bc - if TRUE then DrawBan draws the banana ELSE it erases the banana +SUB DrawBan (xc#, yc#, r, bc) + +SELECT CASE r + CASE 0 + IF bc THEN PUT (xc#, yc#), LBan&, PSET ELSE PUT (xc#, yc#), LBan&, XOR + CASE 1 + IF bc THEN PUT (xc#, yc#), UBan&, PSET ELSE PUT (xc#, yc#), UBan&, XOR + CASE 2 + IF bc THEN PUT (xc#, yc#), DBan&, PSET ELSE PUT (xc#, yc#), DBan&, XOR + CASE 3 + IF bc THEN PUT (xc#, yc#), RBan&, PSET ELSE PUT (xc#, yc#), RBan&, XOR +END SELECT + +END SUB + +'DrawGorilla: +' Draws the Gorilla in either CGA or EGA mode +' and saves the graphics data in an array. +'Parameters: +' x - x coordinate of gorilla +' y - y coordinate of the gorilla +' arms - either Left up, Right up, or both down +SUB DrawGorilla (x, y, arms) + DIM i AS SINGLE ' Local index must be single precision + + 'draw head + LINE (x - Scl(4), y)-(x + Scl(2.9), y + Scl(6)), OBJECTCOLOR, BF + LINE (x - Scl(5), y + Scl(2))-(x + Scl(4), y + Scl(4)), OBJECTCOLOR, BF + + 'draw eyes/brow + LINE (x - Scl(3), y + Scl(2))-(x + Scl(2), y + Scl(2)), 0 + + 'draw nose if ega + IF Mode = 9 THEN + FOR i = -2 TO -1 + PSET (x + i, y + 4), 0 + PSET (x + i + 3, y + 4), 0 + NEXT i + END IF + + 'neck + LINE (x - Scl(3), y + Scl(7))-(x + Scl(2), y + Scl(7)), OBJECTCOLOR + + 'body + LINE (x - Scl(8), y + Scl(8))-(x + Scl(6.9), y + Scl(14)), OBJECTCOLOR, BF + LINE (x - Scl(6), y + Scl(15))-(x + Scl(4.9), y + Scl(20)), OBJECTCOLOR, BF + + 'legs + FOR i = 0 TO 4 + CIRCLE (x + Scl(i), y + Scl(25)), Scl(10), OBJECTCOLOR, 3 * pi# / 4, 9 * pi# / 8 + CIRCLE (x + Scl(-6) + Scl(i - .1), y + Scl(25)), Scl(10), OBJECTCOLOR, 15 * pi# / 8, pi# / 4 + NEXT + + 'chest + CIRCLE (x - Scl(4.9), y + Scl(10)), Scl(4.9), 0, 3 * pi# / 2, 0 + CIRCLE (x + Scl(4.9), y + Scl(10)), Scl(4.9), 0, pi#, 3 * pi# / 2 + + FOR i = -5 TO -1 + SELECT CASE arms + CASE 1 + 'Right arm up + CIRCLE (x + Scl(i - .1), y + Scl(14)), Scl(9), OBJECTCOLOR, 3 * pi# / 4, 5 * pi# / 4 + CIRCLE (x + Scl(4.9) + Scl(i), y + Scl(4)), Scl(9), OBJECTCOLOR, 7 * pi# / 4, pi# / 4 + GET (x - Scl(15), y - Scl(1))-(x + Scl(14), y + Scl(28)), GorR& + CASE 2 + 'Left arm up + CIRCLE (x + Scl(i - .1), y + Scl(4)), Scl(9), OBJECTCOLOR, 3 * pi# / 4, 5 * pi# / 4 + CIRCLE (x + Scl(4.9) + Scl(i), y + Scl(14)), Scl(9), OBJECTCOLOR, 7 * pi# / 4, pi# / 4 + GET (x - Scl(15), y - Scl(1))-(x + Scl(14), y + Scl(28)), GorL& + CASE 3 + 'Both arms down + CIRCLE (x + Scl(i - .1), y + Scl(14)), Scl(9), OBJECTCOLOR, 3 * pi# / 4, 5 * pi# / 4 + CIRCLE (x + Scl(4.9) + Scl(i), y + Scl(14)), Scl(9), OBJECTCOLOR, 7 * pi# / 4, pi# / 4 + GET (x - Scl(15), y - Scl(1))-(x + Scl(14), y + Scl(28)), GorD& + END SELECT + NEXT i +END SUB + +'ExplodeGorilla: +' Causes gorilla explosion when a direct hit occurs +'Parameters: +' X#, Y# - shot location +FUNCTION ExplodeGorilla (x#, y#) + YAdj = Scl(12) + XAdj = Scl(5) + SclX# = ScrWidth / 320 + SclY# = ScrHeight / 200 + IF x# < ScrWidth / 2 THEN PlayerHit = 1 ELSE PlayerHit = 2 + PLAY "MBO0L16EFGEFDC" + + FOR i = 1 TO 8 * SclX# + CIRCLE (GorillaX(PlayerHit) + 3.5 * SclX# + XAdj, GorillaY(PlayerHit) + 7 * SclY# + YAdj), i, ExplosionColor, , , -1.57 + LINE (GorillaX(PlayerHit) + 7 * SclX#, GorillaY(PlayerHit) + 9 * SclY# - i)-(GorillaX(PlayerHit), GorillaY(PlayerHit) + 9 * SclY# - i), ExplosionColor + NEXT i + + FOR i = 1 TO 16 * SclX# + IF i < (8 * SclX#) THEN CIRCLE (GorillaX(PlayerHit) + 3.5 * SclX# + XAdj, GorillaY(PlayerHit) + 7 * SclY# + YAdj), (8 * SclX# + 1) - i, BACKATTR, , , -1.57 + CIRCLE (GorillaX(PlayerHit) + 3.5 * SclX# + XAdj, GorillaY(PlayerHit) + YAdj), i, i MOD 2 + 1, , , -1.57 + NEXT i + + FOR i = 24 * SclX# TO 1 STEP -1 + CIRCLE (GorillaX(PlayerHit) + 3.5 * SclX# + XAdj, GorillaY(PlayerHit) + YAdj), i, BACKATTR, , , -1.57 + FOR Count = 1 TO 200 + NEXT + NEXT i + + ExplodeGorilla = PlayerHit +END FUNCTION + +'GetInputs: +' Gets user inputs at beginning of game +'Parameters: +' Player1$, Player2$ - player names +' NumGames - number of games to play +SUB GetInputs (Player1$, Player2$, NumGames) + COLOR 7, 0 + CLS + + LOCATE 8, 15 + LINE INPUT "Name of Player 1 (Default = 'Player 1'): "; Player1$ + IF Player1$ = "" THEN + Player1$ = "Player 1" + ELSE + Player1$ = LEFT$(Player1$, 10) + END IF + + LOCATE 10, 15 + LINE INPUT "Name of Player 2 (Default = 'Player 2'): "; Player2$ + IF Player2$ = "" THEN + Player2$ = "Player 2" + ELSE + Player2$ = LEFT$(Player2$, 10) + END IF + + DO + LOCATE 12, 56: PRINT SPACE$(25); + LOCATE 12, 13 + INPUT "Play to how many total points (Default = 3)"; game$ + NumGames = VAL(LEFT$(game$, 2)) + LOOP UNTIL NumGames > 0 AND LEN(game$) < 3 OR LEN(game$) = 0 + IF NumGames = 0 THEN NumGames = 3 + + DO + LOCATE 14, 53: PRINT SPACE$(28); + LOCATE 14, 17 + INPUT "Gravity in Meters/Sec (Earth = 9.8)"; grav$ + gravity# = VAL(grav$) + LOOP UNTIL gravity# > 0 OR LEN(grav$) = 0 + IF gravity# = 0 THEN gravity# = 9.8 +END SUB + +'GetNum: +' Gets valid numeric input from user +'Parameters: +' Row, Col - location to echo input +FUNCTION GetNum# (Row, Col) + Result$ = "" + Done = FALSE + WHILE INKEY$ <> "": WEND 'Clear keyboard buffer + + DO WHILE NOT Done + + LOCATE Row, Col + PRINT Result$; CHR$(95); " "; + + Kbd$ = INKEY$ + SELECT CASE Kbd$ + CASE "0" TO "9" + Result$ = Result$ + Kbd$ + CASE "." + IF INSTR(Result$, ".") = 0 THEN + Result$ = Result$ + Kbd$ + END IF + CASE CHR$(13) + IF VAL(Result$) > 360 THEN + Result$ = "" + ELSE + Done = TRUE + END IF + CASE CHR$(8) + IF LEN(Result$) > 0 THEN + Result$ = LEFT$(Result$, LEN(Result$) - 1) + END IF + CASE ELSE + IF LEN(Kbd$) > 0 THEN + BEEP + END IF + END SELECT + LOOP + + LOCATE Row, Col + PRINT Result$; " "; + + GetNum# = VAL(Result$) +END FUNCTION + +'GorillaIntro: +' Displays gorillas on screen for the first time +' allows the graphical data to be put into an array +'Parameters: +' Player1$, Player2$ - The names of the players +' +SUB GorillaIntro (Player1$, Player2$) + LOCATE 16, 34: PRINT "--------------" + LOCATE 18, 34: PRINT "V = View Intro" + LOCATE 19, 34: PRINT "P = Play Game" + LOCATE 21, 35: PRINT "Your Choice?" + + DO WHILE Char$ = "" + Char$ = INKEY$ + LOOP + + IF Mode = 1 THEN + x = 125 + y = 100 + ELSE + x = 278 + y = 175 + END IF + + SCREEN Mode + SetScreen + + IF Mode = 1 THEN Center 5, "Please wait while gorillas are drawn." + + VIEW PRINT 9 TO 24 + + IF Mode = 9 THEN PALETTE OBJECTCOLOR, BackColor + + DrawGorilla x, y, ARMSDOWN + CLS 2 + DrawGorilla x, y, LEFTUP + CLS 2 + DrawGorilla x, y, RIGHTUP + CLS 2 + + VIEW PRINT 1 TO 25 + IF Mode = 9 THEN PALETTE OBJECTCOLOR, 46 + + IF UCASE$(Char$) = "V" THEN + Center 2, "Q B A S I C G O R I L L A S" + Center 5, " STARRING: " + P$ = Player1$ + " AND " + Player2$ + Center 7, P$ + + PUT (x - 13, y), GorD&, PSET + PUT (x + 47, y), GorD&, PSET + Rest 1 + + PUT (x - 13, y), GorL&, PSET + PUT (x + 47, y), GorR&, PSET + PLAY "t120o1l16b9n0baan0bn0bn0baaan0b9n0baan0b" + Rest .3 + + PUT (x - 13, y), GorR&, PSET + PUT (x + 47, y), GorL&, PSET + PLAY "o2l16e-9n0e-d-d-n0e-n0e-n0e-d-d-d-n0e-9n0e-d-d-n0e-" + Rest .3 + + PUT (x - 13, y), GorL&, PSET + PUT (x + 47, y), GorR&, PSET + PLAY "o2l16g-9n0g-een0g-n0g-n0g-eeen0g-9n0g-een0g-" + Rest .3 + + PUT (x - 13, y), GorR&, PSET + PUT (x + 47, y), GorL&, PSET + PLAY "o2l16b9n0baan0g-n0g-n0g-eeen0o1b9n0baan0b" + Rest .3 + + FOR i = 1 TO 4 + PUT (x - 13, y), GorL&, PSET + PUT (x + 47, y), GorR&, PSET + PLAY "T160O0L32EFGEFDC" + Rest .1 + PUT (x - 13, y), GorR&, PSET + PUT (x + 47, y), GorL&, PSET + PLAY "T160O0L32EFGEFDC" + Rest .1 + NEXT + END IF +END SUB + +'Intro: +' Displays game introduction +SUB Intro + + SCREEN 0 + WIDTH 80, 25 + MaxCol = 80 + COLOR 15, 0 + CLS + + Center 4, "Q B a s i c G O R I L L A S" + COLOR 7 + Center 6, "Copyright (C) Microsoft Corporation 1990" + Center 8, "Your mission is to hit your opponent with the exploding" + Center 9, "banana by varying the angle and power of your throw, taking" + Center 10, "into account wind speed, gravity, and the city skyline." + Center 11, "The wind speed is shown by a directional arrow at the bottom" + Center 12, "of the playing field, its length relative to its strength." + Center 24, "Press any key to continue" + + PLAY "MBT160O1L8CDEDCDL4ECC" + SparklePause + IF Mode = 1 THEN MaxCol = 40 +END SUB + +'MakeCityScape: +' Creates random skyline for game +'Parameters: +' BCoor() - a user-defined type array which stores the coordinates of +' the upper left corner of each building. +SUB MakeCityScape (BCoor() AS XYPoint) + + x = 2 + + 'Set the sloping trend of the city scape. NewHt is new building height + Slope = FnRan(6) + SELECT CASE Slope + CASE 1: NewHt = 15 'Upward slope + CASE 2: NewHt = 130 'Downward slope + CASE 3 TO 5: NewHt = 15 '"V" slope - most common + CASE 6: NewHt = 130 'Inverted "V" slope + END SELECT + + IF Mode = 9 THEN + BottomLine = 335 'Bottom of building + HtInc = 10 'Increase value for new height + DefBWidth = 37 'Default building height + RandomHeight = 120 'Random height difference + WWidth = 3 'Window width + WHeight = 6 'Window height + WDifV = 15 'Counter for window spacing - vertical + WDifh = 10 'Counter for window spacing - horizontal + ELSE + BottomLine = 190 + HtInc = 6 + NewHt = NewHt * 20 \ 35 'Adjust for CGA + DefBWidth = 18 + RandomHeight = 54 + WWidth = 1 + WHeight = 2 + WDifV = 5 + WDifh = 4 + END IF + + CurBuilding = 1 + DO + + SELECT CASE Slope + CASE 1 + NewHt = NewHt + HtInc + CASE 2 + NewHt = NewHt - HtInc + CASE 3 TO 5 + IF x > ScrWidth \ 2 THEN + NewHt = NewHt - 2 * HtInc + ELSE + NewHt = NewHt + 2 * HtInc + END IF + CASE 4 + IF x > ScrWidth \ 2 THEN + NewHt = NewHt + 2 * HtInc + ELSE + NewHt = NewHt - 2 * HtInc + END IF + END SELECT + + 'Set width of building and check to see if it would go off the screen + BWidth = FnRan(DefBWidth) + DefBWidth + IF x + BWidth > ScrWidth THEN BWidth = ScrWidth - x - 2 + + 'Set height of building and check to see if it goes below screen + BHeight = FnRan(RandomHeight) + NewHt + IF BHeight < HtInc THEN BHeight = HtInc + + 'Check to see if Building is too high + IF BottomLine - BHeight <= MaxHeight + GHeight THEN BHeight = MaxHeight + GHeight - 5 + + 'Set the coordinates of the building into the array + BCoor(CurBuilding).XCoor = x + BCoor(CurBuilding).YCoor = BottomLine - BHeight + + IF Mode = 9 THEN BuildingColor = FnRan(3) + 4 ELSE BuildingColor = 2 + + 'Draw the building, outline first, then filled + LINE (x - 1, BottomLine + 1)-(x + BWidth + 1, BottomLine - BHeight - 1), BACKGROUND, B + LINE (x, BottomLine)-(x + BWidth, BottomLine - BHeight), BuildingColor, BF + + 'Draw the windows + c = x + 3 + DO + FOR i = BHeight - 3 TO 7 STEP -WDifV + IF Mode <> 9 THEN + WinColr = (FnRan(2) - 2) * -3 + ELSEIF FnRan(4) = 1 THEN + WinColr = 8 + ELSE + WinColr = WINDOWCOLOR + END IF + LINE (c, BottomLine - i)-(c + WWidth, BottomLine - i + WHeight), WinColr, BF + NEXT + c = c + WDifh + LOOP UNTIL c >= x + BWidth - 3 + + x = x + BWidth + 2 + + CurBuilding = CurBuilding + 1 + + LOOP UNTIL x > ScrWidth - HtInc + + LastBuilding = CurBuilding - 1 + + 'Set Wind speed + Wind = FnRan(10) - 5 + IF FnRan(3) = 1 THEN + IF Wind > 0 THEN + Wind = Wind + FnRan(10) + ELSE + Wind = Wind - FnRan(10) + END IF + END IF + + 'Draw Wind speed arrow + IF Wind <> 0 THEN + WindLine = Wind * 3 * (ScrWidth \ 320) + LINE (ScrWidth \ 2, ScrHeight - 5)-(ScrWidth \ 2 + WindLine, ScrHeight - 5), ExplosionColor + IF Wind > 0 THEN ArrowDir = -2 ELSE ArrowDir = 2 + LINE (ScrWidth / 2 + WindLine, ScrHeight - 5)-(ScrWidth / 2 + WindLine + ArrowDir, ScrHeight - 5 - 2), ExplosionColor + LINE (ScrWidth / 2 + WindLine, ScrHeight - 5)-(ScrWidth / 2 + WindLine + ArrowDir, ScrHeight - 5 + 2), ExplosionColor + END IF +END SUB + +'PlaceGorillas: +' PUTs the Gorillas on top of the buildings. Must have drawn +' Gorillas first. +'Parameters: +' BCoor() - user-defined TYPE array which stores upper left coordinates +' of each building. +SUB PlaceGorillas (BCoor() AS XYPoint) + + IF Mode = 9 THEN + XAdj = 14 + YAdj = 30 + ELSE + XAdj = 7 + YAdj = 16 + END IF + SclX# = ScrWidth / 320 + SclY# = ScrHeight / 200 + + 'Place gorillas on second or third building from edge + FOR i = 1 TO 2 + IF i = 1 THEN BNum = FnRan(2) + 1 ELSE BNum = LastBuilding - FnRan(2) + + BWidth = BCoor(BNum + 1).XCoor - BCoor(BNum).XCoor + GorillaX(i) = BCoor(BNum).XCoor + BWidth / 2 - XAdj + GorillaY(i) = BCoor(BNum).YCoor - YAdj + PUT (GorillaX(i), GorillaY(i)), GorD&, PSET + NEXT i + +END SUB + +'PlayGame: +' Main game play routine +'Parameters: +' 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 +