'=========================================================================== ' Subject: QBASIC ROCKWARS Date: 10-05-96 (15:14) ' Author: Brennen Bearnes Code: QB, QBasic, PDS ' Origin: bbearnes@worldnet.att.net Packet: GAMES.ABC '=========================================================================== 'QBasic Rockwars, by Brennen Bearnes 'You play the part of the blue castle. You've been attacked by 'the red castle, who has started sending robotic tanks equipped with 'a short range death ray at you. Fortunately, you've been hard at work 'on your own secret weapon, a powerful catapult that can launch rocks 'all the way to the other side of the screen. 'How to play: 'A tank will start coming at you as soon as the game begins. If the 'red castle is fairly close, then you should shoot the tank first. 'Every time you blow up a tank, the red castle sends another one, 'so sooner or later, you'll have to hit the castle. To fire, press 'F1, and type in the angle (10-180) and velocity (0-100) you want. Be 'sure to take the wind into account. If the tank gets close enough, 'then you're toast. 'Brent P. Newhall did all the code for the explosions, as well as the star 'field, and a number of other small but effective changes. 'The little moon orbiting a planet in the background was done 'by Marco Koegler (and thanks to everyone else that told me how to do it). 'I figured out how to plot the projectiles from GORILLA.BAS, which I 'found on an old computer at school. 'Suggestions are welcome, and if you improve this in any way, please 'send me a copy. 'bbearnes@worldnet.att.net 'http://www.geocities.com/SiliconValley/Park/8994/ ' Brent P. Newhall edited 9/30/96 ' Notes: The explode code now restores the screen to how it looked prior ' to the explosion. I then added code to erase the bullet and ' exploded item just after the explosion. I also added the stars. ' Before, you could enter an angle of zero and just wipe out ' anything before you. Now the angle can be no less than 10. ' I've also cleaned up the code a bit, making it more readable, ' less time- and memory-intensive, etc. DECLARE SUB newTank () DECLARE SUB drawTank () DECLARE SUB newRock () DECLARE SUB drawRock () DECLARE SUB explode (green%, blue%, red%, boomX, boomY, boomSize) CONST pi = 3.141592654# TYPE arctype Radius AS INTEGER colr AS INTEGER p1 AS SINGLE p2 AS SINGLE END TYPE 'Variables that control the rock DIM SHARED rockAngle DIM SHARED rockSpeed DIM SHARED startRockX DIM SHARED startRockY DIM SHARED oldRockX DIM SHARED oldRockY DIM SHARED rock1exist DIM SHARED t 'time DIM SHARED rockX DIM SHARED rockY DIM SHARED startRockXvel DIM SHARED startRockYvel DIM SHARED gravity DIM SHARED wind 'The castles and tank. DIM SHARED castle2X DIM SHARED castleX DIM SHARED tankExist DIM SHARED TankX DIM SHARED oldTankX DIM SHARED tankSpeed DIM SHARED castleExist DIM SHARED castle2Exist DIM SHARED x1 AS INTEGER, y1 AS INTEGER, x2 AS INTEGER, y2 AS INTEGER DIM SHARED ExplodeHold(1 TO 10000) AS INTEGER castleExist = 1 castle2Exist = 1 SCREEN 13 'GET the player's castle. DIM SHARED castle%(15, 15) LINE (5, 5)-(20, 20), 1, BF LINE (8, 5)-(10, 7), 0, BF LINE (12, 5)-(14, 7), 0, BF LINE (16, 5)-(18, 7), 0, BF LINE (10, 15)-(15, 20), 0, BF GET (5, 5)-(20, 20), castle% CLS 'GET the computer's castle. DIM SHARED castle2%(15, 15) LINE (5, 5)-(20, 20), 4, BF LINE (8, 5)-(10, 7), 0, BF LINE (12, 5)-(14, 7), 0, BF LINE (16, 5)-(18, 7), 0, BF LINE (10, 15)-(15, 20), 0, BF GET (5, 5)-(20, 20), castle2% CLS 'GET the tank DIM SHARED tank%(11, 8) LINE (2, 4)-(10, 6), 2, BF LINE (5, 1)-(8, 4), 2, BF LINE (1, 2)-(5, 2), 2 CIRCLE (3, 6), 2, 2 CIRCLE (8, 6), 2, 2 GET (1, 1)-(11, 8), tank% CLS 'The tank firing. DIM SHARED tank2%(11, 8) LINE (2, 4)-(10, 6), 2, BF LINE (5, 1)-(8, 4), 2, BF LINE (1, 1)-(5, 3), 2 CIRCLE (3, 6), 2, 2 CIRCLE (8, 6), 2, 2 GET (1, 1)-(11, 8), tank2% CLS 'The center of the planet planetX = 180: planetY = 45 'Draw the planet FOR circ% = 1 TO 8 CIRCLE (planetX, planetY), circ%, 9 CIRCLE (planetX, planetY + 1), circ%, 9 NEXT circ% LINE (planetX - 8, planetY)-(planetX + 8, planetY), 4 LINE (planetX - 8, planetY - 2)-(planetX + 8, planetY - 2), 12 LINE (planetX - 7, planetY - 3)-(planetX + 7, planetY - 3), 12 LINE (planetX - 5, planetY - 5)-(planetX + 5, planetY - 5), 4 LINE (planetX - 8, planetY + 3)-(planetX + 8, planetY + 3), 4 LINE (planetX - 6, planetY + 5)-(planetX + 6, planetY + 5), 4 CIRCLE (planetX + 2, planetY + 4), 2, 4 CIRCLE (planetX + 2, planetY + 4), 1, 4 CIRCLE (planetX + 3, planetY + 4), 1, 4 'Draw the ground LINE (0, 175)-(320, 175), 10 PAINT (0, 176), 10, 1 'PUT the castles castleX = 15 PUT (castleX, 159), castle% RANDOMIZE TIMER castle2X = INT(RND * 175) + 175 IF castle2X >= 285 THEN castle2X = 285 PUT (castle2X, 159), castle2% 'The code to make the moon "orbit" the planet was done by Marco Koegler orbitRadius = 30 'Radius of the orbit moonAngle = 0 'Initialize the moons angle oldMoonX = planetX + 75: oldMoonY = planetY gravity = 9.8 'Display stars FOR cnt% = 1 TO 75 PSET (INT(RND * 319), INT(RND * 120) + 30), INT(RND * 15 + 15) NEXT cnt% DO moonAngle = moonAngle + .5 IF moonAngle = 360 THEN moonAngle = 0 theta = moonAngle * (pi / 180) moonX = planetX + orbitRadius * (COS(theta)) moonY = planetY - orbitRadius * (SIN(theta)) 'Erase old moon CIRCLE (oldMoonX, oldMoonY), 2, 0 'Draw new moon CIRCLE (moonX, moonY), 2, 8 oldMoonX = moonX: oldMoonY = moonY ptime! = TIMER: WHILE ptime! = TIMER: WEND ' Pause K$ = INKEY$ IF LEN(K$) = 2 THEN SELECT CASE ASC(RIGHT$(K$, 1)) CASE 59 'F1 IF rock1exist = 0 THEN newRock END IF END SELECT ELSEIF LEN(K$) = 1 THEN SELECT CASE ASC(K$) CASE 27: quit = 1 END SELECT END IF IF rock1exist = 1 THEN drawRock END IF IF tankExist = 0 AND castle2Exist = 1 THEN newTank ELSEIF tankExist = 1 THEN drawTank END IF IF castleExist = 0 THEN '"Melt" the screen and end the game if the player loses. quit = 2 ELSEIF castle2Exist = 0 AND tankExist = 0 THEN 'If the red castle and tank are both blown up, then end the game. quit = 3 END IF LOOP UNTIL quit > 0 IF quit = 2 THEN '"Melt" the screen and end the game if the player loses. LOCATE 8, 15: PRINT "you lose" LOCATE 9, 14: PRINT "the end" SLEEP 1 DIM melt%(3000) FOR RR = 1 TO 3000 RANDOMIZE TIMER XX = INT(RND * 271) RANDOMIZE TIMER YX = INT(RND * 150) GET (XX, YX)-(XX + 48, YX + 48), melt% PUT (XX, YX + 1), melt%, PSET IF INKEY$ = CHR$(27) THEN END NEXT RR ELSEIF quit = 3 THEN 'If the red castle and tank are both blown up, then end the game. LOCATE 15, 15: PRINT "you win" END IF END SUB drawRock oldRockX = rockX oldRockY = rockY 'Calculate the next position of the rock rockX = startRockX + (startRockXvel * t) + (.5 * (wind / 5) * t ^ 2) rockY = startRockY + ((-1 * (startRockYvel * t)) + (.5 * gravity * t ^ 2)) * (200 / 350) IF rockY >= 174 THEN 'Do an explosion when the rock hits the "ground". rock1exist = 0 green% = 20 blue% = 0 boomX = rockX boomY = rockY boomSize = 6 explode green%, blue%, red%, boomX, boomY, boomSize CIRCLE (oldRockX, oldRockY), 1, 0 ' Erase rock ELSEIF rockY >= 159 AND rockX >= castle2X AND rockX <= castle2X + 15 THEN 'Do an explosion when the rock hits the enemy castle. IF castle2Exist = 1 THEN rock1exist = 0 castle2Exist = 0 green% = 0 blue% = 0 boomX = rockX boomY = rockY boomSize = 50 explode green%, blue%, red%, boomX, boomY, boomSize CIRCLE (oldRockX, oldRockY), 1, 0 ' Erase rock PUT (castle2X, 159), castle2% ' Erase enemy castle END IF ELSEIF rockY >= 167 AND rockX >= TankX AND rockX <= TankX + 10 THEN 'Do an explosion if rock hits the tank. tankExist = 0 rock1exist = 0 green% = 20 blue% = 0 boomX = TankX boomY = rockY boomSize = 30 explode green%, blue%, red%, boomX, boomY, boomSize CIRCLE (oldRockX, oldRockY), 1, 0 ' Erase rock PUT (INT(TankX), 167), tank%, XOR ' Erase tank END IF IF rockX >= 319 OR rockX <= 1 THEN rock1exist = 0 CIRCLE (oldRockX, oldRockY), 1, 0 END IF IF rock1exist = 1 THEN CIRCLE (oldRockX, oldRockY), 1, 0 CIRCLE (rockX, rockY), 1, 12 ELSEIF rock1exist = 0 THEN rockX = 0 rockY = 0 END IF t = t + .1 END SUB SUB drawTank 'Move the tank, or if the tank is close enough, blow up the player's 'castle. tankSpeed = .5 IF TankX > castleX + 60 THEN 'Make the tank try to avoid the rocks (doesn't work very well, but can 'make the game a little more challenging). IF TankX - rockX < 20 AND TankX - rockX > -1 THEN tankSpeed = -.8 END IF oldTankX = TankX TankX = TankX - tankSpeed ELSEIF TankX <= castleX + 60 THEN PUT (INT(TankX), 167), tank2%, PSET SLEEP 1 PALETTE 95, 60 LINE (INT(TankX) - 2, 167)-(castleX + 15, 162), 95 FOR cnt% = 1 TO 30 PALETTE 95, INT(RND * 30 + 30) ptime! = TIMER: WHILE ptime! = TIMER: WEND ' Pause NEXT cnt% PALETTE 95, 0 tankExist = 0 green% = 0 blue% = 30 boomX = castleX + 15 boomY = 162 boomSize = 50 explode green%, blue%, red%, boomX, boomY, boomSize castleExist = 0 END IF PUT (INT(oldTankX), 167), tank%, XOR PUT (INT(TankX), 167), tank%, PSET END SUB SUB explode (green%, blue%, red%, boomX, boomY, boomSize) 'This code started as EXPLODE.BAS by Brent P. Newhall. I've only made a 'few minor changes. The comments are all his. ''I was thinking about that "I need fire and an exploding graphic" post ''and came up with this simple explosion program. Any suggestions, ''comments, etc. are welcome with open arms. ''NOTES: There are two lines that do not wrap properly; you'll be able to ''find them easily. Also, NumArcs is set to 100, which does an ''acceptable explosion on my 486DX2/50 with 8 megs of RAM. You Pentium ''people should be able to get a much nicer explosion if you set NumArcs ''equal to 1000 or so. ''The program sets colors 100 to 131 to varying shades of red, orange, ''and yellow for the explosive effect, with the nice side-effect that 'you can theoretically do several explosions at once. NumArcs = 65 DIM arc(1 TO NumArcs) AS arctype RANDOMIZE TIMER FOR cnt% = 1 TO NumArcs ' Initialise arc(cnt%).Radius = 0 arc(cnt%).p1 = RND * 5.8 arc(cnt%).p2 = arc(cnt%).p1 + (RND / 2) arc(cnt%).colr = INT(RND * 5 + 100) NEXT cnt% red% = 63 ' Start it deep red FOR cnt% = 100 TO 130 ' Change colors PALETTE cnt%, red% + 256 * green% + 65536 * blue% IF cnt% <= 114 THEN ' Lower red, increase yellow red% = red% - 2 green% = green% + 2 ELSE ' Lower red and yellow red% = red% - 2 green% = green% - 2 END IF NEXT cnt% PALETTE 131, 0 TimeCnt% = 0 x1 = boomX - boomSize IF x1 < 0 THEN x1 = 0 y1 = boomY - boomSize IF y1 < 0 THEN y1 = 0 x2 = boomX + boomSize IF x2 > 319 THEN x2 = 319 y2 = boomY + boomSize IF y2 > 199 THEN y2 = 199 GET (x1, y1)-(x2, y2), ExplodeHold(1) DO TimeCnt% = TimeCnt% + 1 FOR CurrArc% = 1 TO NumArcs IF arc(CurrArc%).Radius > 4 THEN ' Erase previous arc CIRCLE (boomX, boomY), arc(CurrArc%).Radius - 5, 0, arc(CurrArc%).p1, arc(CurrArc%).p2 END IF IF arc(CurrArc%).Radius = 0 THEN ' Not yet alive ' About 30% of the time, create a new arc IF RND > .7 THEN arc(CurrArc%).Radius = 1 ELSEIF arc(CurrArc%).colr = 131 THEN ' Dead REM Do Nothing ELSE arc(CurrArc%).Radius = arc(CurrArc%).Radius + 1 ' Increase radius arc(CurrArc%).colr = arc(CurrArc%).colr + 1 ' Increase color ' Draw arc CIRCLE (boomX, boomY), arc(CurrArc%).Radius, arc(CurrArc%).colr, arc(CurrArc%).p1, arc(CurrArc%).p2 END IF NEXT CurrArc% t! = TIMER: WHILE t! = TIMER: WEND ' Pause IF TimeCnt% >= boomSize THEN quitExplode = 1 LOOP UNTIL quitExplode > 0 PUT (x1, y1), ExplodeHold(1), PSET END SUB SUB newRock 'initialize the wind, and tell the player. RANDOMIZE TIMER: windirec = RND * 2: LOCATE 1, 1: PRINT SPC(30); IF windirec <= 1 THEN RANDOMIZE TIMER: wind = RND * -10 LOCATE 1, 1: PRINT "wind: "; wind; "<-" ELSEIF windirec > 1 THEN RANDOMIZE TIMER: wind = RND * 10 LOCATE 1, 1: PRINT "wind:"; wind; "-> " END IF 'Get player input for angle and velocity, and initialize the rock. 'Velocity can range from 0 to 100, and angle can be inbetween 10 and 180. LOCATE 2, 1: PRINT "Angle: " DO LOCATE 2, 7: PRINT " "; LOCATE 2, 7: INPUT "", rockAngle LOOP UNTIL rockAngle >= 10 AND rockAngle <= 180 LOCATE 3, 1: PRINT "Velocity: " DO LOCATE 3, 10: PRINT " "; LOCATE 3, 10: INPUT "", rockSpeed LOOP UNTIL rockSpeed >= 0 AND rockSpeed <= 100 LINE (1, 1)-(50, 50), 0 startRockX = castleX + 6 startRockY = 157 oldRockX = startRockX oldRockY = startRockY rock1exist = 1 rockAngle = rockAngle / 180 * pi startRockXvel = COS(rockAngle) * rockSpeed startRockYvel = SIN(rockAngle) * rockSpeed t = 0 drawRock END SUB SUB newTank 'Initialize tank. tankExist = 1 TankX = castle2X - 12 oldTankX = castle2X - 12 PUT (castle2X, 159), castle2%, PSET drawTank END SUB