' Tank Game!!!!!!!!!!!!! ' ' By Dave Duvenaud ' 'contact me at duvenaud@escape.ca ' ' Press F5 to run, or Ctrl+Break to exit. ' if F5 doesn't work, press shift F5 'much thanks to the guy who made snoopy for the timing code, but I found 'way to improve it further by putting the stored timer variable at the 'beginning of the loop. This means that the amount of stuff happening ' in the game won't affect the speed at all, unless it surpasses the given 'time. ' ' Made in 1998 but the landscape code in 1997 ' ' Oh yeah, you might want to use the explosion code which I took 'from MY other game, star warrior. DIM cas AS LONG DIM steep AS LONG DIM tank AS STRING DIM lkas AS STRING * 3 DIM SHARED x AS INTEGER DIM SHARED y AS INTEGER DIM tankx(5) AS INTEGER DIM tanky(5) AS INTEGER DIM shotx(5) AS INTEGER DIM shoty(5) AS INTEGER guypic$ = " h2 e1 r1 f1 g1 d2 r2 e1 g1 l4 h1 f1 r2 d2 f2 h2 g2" GOTO 9909 drawtank: PSET (tankx, tanky), 0 DRAW "c2" DRAW "x" + VARPTR$(tank$) PAINT (tankx, tanky - 2), 2 RETURN tankmask: PSET (tankx, tanky - 1), 0 DRAW "c0" DRAW "x" + VARPTR$(tank$) RETURN 9909 tank$ = "l8 h3 r4 e3 r8 f3 r4 g3 l8" DIM colo AS INTEGER SCREEN 13 CLS colo = 4 RANDOMIZE TIMER boz = INT(RND * 160) + 20 RANDOMIZE TIMER bo = INT(RND * 280) + 20 1 LOCATE 12, 12: PRINT " Tank Game" LOCATE 13, 10: PRINT "By David Duvenaud" explosion = explosion + 1 IF colo = 4 THEN SOUND 37, .07 'when the circle is red,make a sound CIRCLE (bo, boz), explosion, colo 'explosion is the radius CIRCLE (bo, boz + 1), explosion, colo 'IF explosion > 20 AND col = 4 THEN col = 6 'this would make it part IF explosion > 30 THEN 'orange IF colo = 0 THEN RANDOMIZE TIMER 'I took this routine boz = INT(RND * 160) + 20 'from my first game, RANDOMIZE TIMER ' star warrior. bo = INT(RND * 280) + 20 explosion = 0 colo = 4 ELSE colo = 0 explosion = 0 END IF END IF IF INKEY$ = "" THEN GOTO 1 steep = 65 numtanks = 2 33 main: CLS LOCATE 4, 10: PRINT "Mushroom cloud" LOCATE 5, 12: PRINT "Main menu" PRINT PRINT PRINT COLOR 4 PRINT " (1) To the battlefeild! " COLOR 15 PRINT " (2) Options" PRINT " (3) Info " PRINT " (4) Credits" PRINT " (5) Exit" FOR i = 1 TO 5 tankx = 40 * i + 5 tanky = 57 GOSUB drawtank DRAW "e7" NEXT PRINT PRINT PRINT PRINT " Steepness: "; steep PRINT " Players: "; numtanks 'IF artillery = 1 THEN 'PRINT " Artillery: On" 'ELSE PRINT " Artillery: Off" 'END IF DO SELECT CASE INKEY$ CASE "1": GOTO makescreen CASE "2": GOTO 88 CASE "3": GOTO info CASE "4": GOSUB Credits CASE "5": END CASE ELSE END SELECT LOOP info: CLS SCREEN 9 PRINT PRINT " Info" PRINT PRINT " This game is like scorched earth, with one major difference: no turns! " PRINT "You can only have one shot at a time but you don't have to sit there while a" PRINT "shell is heading straight for you. Programmed in Qbasic. 1998" PRINT PRINT "Dont hold down the Keys!!!!!!!!!!!" PRINT " Controls" PRINT PRINT "Player 1 2 3 4" PRINT PRINT "Shoot: c / 0 (Insert) 7" PRINT "Gun left: a j Left Arrow 4 " PRINT "Gun right: d l Right Arrow 6" PRINT "Power Up: w i Up Arrow 8" PRINT "Power Down: s k Down Arrow 5 " PRINT PRINT "q to quit" COLOR 10 PRINT "You gotta have Numlock on!" COLOR 15 PRINT "Your power can be from 1 to 20" PRINT "When your tank dies, your guy ejects from the tank." PRINT "You can't control him, because he dies on impact! Hahahaha!" PRINT "The object of the game is to kill the other tanks." WHILE INKEY$ = "": WEND SCREEN 13 GOTO 33 Credits: CLS SCREEN 9 PRINT PRINT PRINT " Credits" PRINT PRINT " Programmed entirley by Dave Duvenaud" PRINT PRINT " Testers:" PRINT PRINT "John Duvenaud James Challis" PRINT "Steven Duvenaud Bayard Devris" PRINT PRINT PRINT "I have made a few other games, but this is my best so far." PRINT "The only one I have distributed is Star Warrior." WHILE INKEY$ = "": WEND SCREEN 13 GOTO 33 88 CLS LOCATE 5, 15: PRINT "Options" LOCATE 10, 10: INPUT "Steepness(1 to 100):", lkas$ IF VAL(lkas$) > 100 OR VAL(lkas$) < 1 THEN GOTO 88 ELSE steep = VAL(lkas$) 4 LOCATE 15, 1: PRINT " Players(2 to 4): " DO slop$ = INKEY$ IF slop$ > "4" OR slop$ < "2" THEN GOTO 4 ELSE LOCATE 15, 28: PRINT slop$ numtanks = VAL(slop$): GOTO 29 LOOP PRINT 29 LOCATE 18, 13: PRINT "Accept Options?" DO poop$ = INKEY$ IF poop$ = "y" THEN GOTO main IF poop$ = "n" THEN GOTO 88 GOTO 29 LOOP makescreen: 'Makes the screen SCREEN 9 CLS LOCATE 1, 12: PRINT "Creating Screen" cas = 170 'cas is the height of the land, this starts it in middle jas = 27 bottom = 345 'bottom is the lowest point that the land can go FOR has = 1 TO 640 'Creates landscape RANDOMIZE TIMER mas = INT(RND * 3) + 1 SELECT CASE mas CASE 2: sas = sas + steep / 100 CASE 3: sas = sas - steep / 100 CASE 4: sas = sas + steep / 100 CASE 5: sas = sas - steep / 100 END SELECT cas = cas + sas IF cas < 60 THEN 'keeps land height within screen sas = 0 cas = 60 END IF IF cas > bottom THEN cas = bottom sas = 0 END IF LINE (has, cas)-(has, bottom), 6 'Draws landscape has = has + 1 'I added this to make the terrain less bumpy LINE (has, cas)-(has, bottom), 6 IF has = 150 OR has = 300 OR has = 450 THEN 'Keeps user waiting LOCATE 1, jas: PRINT "." jas = jas + 1 END IF NEXT has LOCATE 1, 10: PRINT " " 'erases "creating screen" LINE (1, 28)-(639, 346), 7, B 'draws border LINE (2, 29)-(638, 345), 7, B LOCATE 1, 2: PRINT "Do you like this landscape? (Y or N)" DO inky$ = INKEY$ 'decides yes or no SELECT CASE inky$ CASE "n", "N": GOTO makescreen CASE "y", "Y": GOTO 101 END SELECT LOOP 101 'places tanks LOCATE 1, 2: PRINT " " FOR h = 1 TO numtanks tanky(h) = 38 tankx(h) = 100 + (500 / numtanks) * (h - 1) 'spaces the tanks evenly tankx = tankx(h) tanky = tanky(h) 'GOSUB drawtank NEXT h DIM land(6) AS INTEGER 'to keep track of which tanks are on the ground ' I added this so that if the player used land(5) = 5 'less than five players it would still land(4) = 5 'check to see land(3) = 5 'if all the tanks had landed land(2) = 5 DO IF INKEY$ = CHR$(27) THEN END 'escape key FOR mamja = 1 TO numtanks IF POINT(tankx(mamja), tanky(mamja) + 5) = 7 OR POINT(tankx(mamja), tanky(mamja) + 1) = 6 OR POINT(tankx(mamja), tanky(mamja) + 1) = 7 THEN land(mamja) = 5 ELSE tanky(mamja) = tanky(mamja) + 1 tanky = tanky(mamja) tankx = tankx(mamja) GOSUB tankmask GOSUB drawtank land(mamja) = 3 END IF NEXT mamja 'checks to see if they all touched ground IF land(1) = 5 AND land(2) = 5 AND land(3) = 5 AND land(4) = 5 AND land(5) = 5 THEN notdone = 5 LOOP UNTIL notdone = 5 DIM rad(10) AS INTEGER DIM ang(5) AS INTEGER DIM grav(5) AS DOUBLE DIM thrust(5) AS DOUBLE shotpic$ = "u1 d2 u1 l1 r2" soundon = 1 GOTO 2 'so that it skips this blowup: rad(c) = rad(c) + 1 IF col(c) = 4 AND soundon = 1 THEN SOUND 37, .07 CIRCLE (explox(c), exploy(c)), rad(c), col(c) CIRCLE (explox(c), exploy(c) - 1), rad(c), col(c) IF col = 0 THEN rad(c) = rad(c) + 1 'make it erase faster CIRCLE (explox(c), exploy(c)), rad(c), col(c) CIRCLE (explox(c), exploy(c) - 1), rad(c), col(c) LINE (1, 28)-(639, 346), 7, B 'draws border LINE (2, 29)-(638, 345), 7, B END IF IF rad(c) > 35 THEN IF col(c) = 4 THEN rad(c) = 0 col(c) = 0 ELSE LINE (1, 28)-(639, 346), 7, B 'draws border LINE (2, 29)-(638, 345), 7, B explo(c) = 0 END IF END IF RETURN 2 dead(3) = 1 dead(2) = 1 dead(1) = 1 dead(4) = 1 'makes all of them dead dead(5) = 1 FOR i = 0 TO numtanks 'revives the real players dead(i) = 0 power(i) = 7 'and sets all the variables health(i) = 100 guygrav(i) = -3 guythrust(i) = -1 shot(i) = 0 explo(i) = 0 rad(i) = 0 ang(i) = 0 guy(i) = 0 guydead(i) = 0 notdone = 0 mamja(i) = 0 NEXT i winner = 0 guydead = 0 dead = 0 'GOSUB drawcan 'If you're looking at the code, you should know that c is the 'player number, and that h is the player number for keys '************************************************ beginning: 'the start of the loop*************************** FOR c = 1 TO numtanks w! = TIMER 76 IF c = 1 OR c = 2 OR c = 3 THEN LOCATE 1, (27 * c) - 26 ELSE 'puts them on two lines IF c > 3 AND c < 6 THEN LOCATE 2, (27 * (c - 2)) - 26: 'it was crashing here END IF 'so I added an if PRINT "Tank"; c; "Pwr:"; power(c); "Armor:"; health(c) IF guy(c) = 1 THEN IF POINT(guyx(c), guyy(c) - 4) = 6 OR POINT(guyx(c), guyy(c) + 10) = 6 OR POINT(guyx(c) - 3, guyy(c)) = 6 OR POINT(guyx(c), guyy(c) - 4) = 2 OR POINT(guyx(c) - 5, guyy(c) + 4) = 2 OR guyx(c) < 1 OR guyx(c) > 640 OR guyy(c) > 350 THEN LINE (guyx(c), guyy(c))-(guyx(c), guyy(c)), 0 DRAW "c0" DRAW "x" + VARPTR$(guypic$) guy(c) = 0 'this is the guy sub guydead(c) = 1 ' it's alot like the shot sub guydead = guydead + 1 ELSE guygrav(c) = guygrav(c) + .2 LINE (guyx(c), guyy(c))-(guyx(c), guyy(c)), 0 DRAW "c0" DRAW "x" + VARPTR$(guypic$) guyy(c) = guyy(c) + guygrav(c) guyx(c) = guyx(c) + guythrust(c) LINE (guyx(c), guyy(c))-(guyx(c), guyy(c)), 0 DRAW "c15" DRAW "x" + VARPTR$(guypic$) END IF END IF IF shot(c) = 1 THEN 'checks if a shot is in the air LINE (shotx(c), shoty(c))-(shotx(c), shoty(c)), 0 DRAW "c0" DRAW "x" + VARPTR$(shotpic$) 'erases shot shotx(c) = shotx(c) + thrust(c) shoty(c) = shoty(c) + grav(c) grav(c) = grav(c) + .2 LINE (shotx(c), shoty(c))-(shotx(c), shoty(c)), 0 DRAW "c15" DRAW "x" + VARPTR$(shotpic$) 'draws shot 'IF POINT(shotx(c) - 2, shoty(c)) = 7 OR POINT(shotx(c) + 2, shoty(c)) = 7 OR POINT(shotx(c) + 1, shoty(c) - 1) = 7 OR POINT(shotx(c) - 1, shoty(c) - 1) = 7 THEN 'IF shoty(c) < 40 THEN grav(c) = -grav(c) 'bounce off roof 'IF shoty(c) > 500 THEN grav(c) = -grav(c) 'bounce off floor 'ELSE thrust(c) = -thrust(c) 'Bounce off walls 'PRINT "Boing!" 'END IF IF POINT(shotx(c) - 1, shoty(c) + 1) <> 0 OR POINT(shotx(c) + 1, shoty(c) + 1) <> 0 OR POINT(shotx(c) + 1, shoty(c) - 1) <> 0 OR POINT(shotx(c) - 1, shoty(c) - 1) <> 0 THEN IF explo(c) = 1 THEN 'this is also a complex IF col(c) = 0 THEN rad(c) = 35 'peice of work... don't try rad(c) = rad(c) + 1 'to understand it. FOR i = 1 TO rad(c) CIRCLE (explox(c), exploy(c)), i, 0 CIRCLE (explox(c), exploy(c) - 1), i, 0 NEXT i END IF explox(c) = shotx(c) exploy(c) = shoty(c) col(c) = 4 'changes explosion color rad(c) = 0 'resets explosion radius explo(c) = 1 'says that it's exploding shot(c) = 0 'erases the shot END IF END IF 98 IF explo(c) = 1 THEN kn = c FOR kn = 1 TO numtanks 'this speeds up the explosions GOSUB blowup 'and checks if it's exploding NEXT kn END IF IF dead(c) = 1 THEN IF numtanks - guydead < 2 THEN GOTO 87 IF c = numtanks THEN EXIT FOR c = c + 1 'checks if that tank is dead! GOTO 76 ' so that if first tank dies, succesive guys can go flying END IF ' all the stuff before this happens even if tank is dead IF numtanks - guydead < 2 THEN GOTO 87 IF POINT(tankx(c), tanky(c) - 8) = 4 THEN 'checks if tank is hurt blast(c) = 1 health(c) = health(c) - 4 IF health(c) = 0 THEN PRINT "Tank number "; c; " died!" dead(c) = 1 guy(c) = 1 guyx(c) = tankx(c) guyy(c) = tanky(c) - 7 dead = dead + 1 RANDOMIZE TIMER 'this makes the guy go randomly a = INT(RND * 8) - 4 'flying in any direction guythrust(c) = a RANDOMIZE TIMER s = INT(RND * 6) - 8 guygrav(c) = s IF numtanks - guydead = 1 THEN 87 PRINT "Game Over." 'Declare the winner! FOR p = 1 TO numtanks IF dead(p) = 0 THEN winner = p END IF NEXT IF winner <> 0 THEN PRINT "Player"; winner; "is the winner!" ELSE PRINT "It's a Tie" END IF s! = TIMER DO LOOP UNTIL TIMER > s! + .1 SLEEP SCREEN 13 GOTO 33 'That's all, folks END IF END IF END IF IF POINT(tankx(c), tanky(c)) = 0 THEN 'so that it redraws the tank after a hit FOR j = 1 TO 10 ' a hit IF explo(c) = 1 THEN GOSUB blowup NEXT j LINE (tankx(c), tanky(c))-(tankx(c), tanky(c)), 0 DRAW "c2" DRAW "x" + VARPTR$(tank$) PAINT (tankx(c), tanky(c) - 2), 2 END IF sps$ = INKEY$ SELECT CASE sps$ 'checks the keys CASE CHR$(27): END CASE "w": h = 1: GOSUB powerup CASE "s": h = 1: GOSUB powerdown CASE "c": h = 1: GOSUB shoot CASE "d": h = 1: GOSUB angright CASE "a": h = 1: GOSUB angleft CASE "i": h = 2: GOSUB powerup CASE "k": h = 2: GOSUB powerdown CASE "/": h = 2: GOSUB shoot CASE "l": h = 2: GOSUB angright CASE "j": h = 2: GOSUB angleft CASE "8": h = 4: GOSUB powerup CASE "5": h = 4: GOSUB powerdown CASE "7": h = 4: GOSUB shoot CASE "6": h = 4: GOSUB angright CASE "4": h = 4: GOSUB angleft CASE CHR$(0) + "H": h = 3: GOSUB powerup CASE CHR$(0) + "P": h = 3: GOSUB powerdown CASE CHR$(0) + "K": h = 3: GOSUB angleft CASE CHR$(0) + "M": h = 3: GOSUB angright CASE "0": h = 3: GOSUB shoot CASE ELSE END SELECT IF POINT(tankx(c), tanky(c) + 1) = 0 THEN 'makes tank fall GOSUB erasecan 'otherwise it will leave cannon trails LINE (tankx(c), tanky(c))-(tankx(c), tanky(c)), 0 DRAW "c0" DRAW "x" + VARPTR$(tank$) tanky(c) = tanky(c) + 1 LINE (tankx(c), tanky(c))-(tankx(c), tanky(c)), 0 DRAW "c2" DRAW "x" + VARPTR$(tank$) PAINT (tankx(c), tanky(c) - 2), 2 GOSUB erasecan ' it used to leave a trail of cannons when you 'fell before I added this GOSUB drawcan 'so even when we're falling we know our angle END IF NEXT c 'end of loop DO LOOP UNTIL TIMER > w! + .01 GOTO beginning drawcan: IF dead(h) = 1 THEN RETURN ang = ang(h) LINE (tankx(h), tanky(h) - 7)-(tankx(h), tanky(h) - 7), 0 DRAW "c2" DRAW "TA=" + VARPTR$(ang) DRAW "u5" ang = -ang DRAW "TA=" + VARPTR$(hgd) RETURN erasecan: ang = ang(h) LINE (tankx(h), tanky(h) - 7)-(tankx(h), tanky(h) - 7), 0 DRAW "c0" DRAW "TA=" + VARPTR$(ang) DRAW "u5" ang = -ang DRAW "TA=" + VARPTR$(hhgf) 'resets the angle RETURN powerup: power(h) = power(h) + 1 IF power(h) > 20 THEN power(h) = 20 RETURN powerdown: power(h) = power(h) - 1 IF power(h) < 1 THEN power(h) = 1 RETURN shoot: IF dead(h) = 1 THEN RETURN 'can't shoot if he's dead IF shot(h) = 0 THEN IF ang(h) < 0 THEN thrust(h) = (-power(h) / 90) * ang(h) 'these formulas took me a long time grav(h) = -power(h) + thrust(h) ' to get right. ELSE thrust(h) = (-power(h) / 90) * ang(h) 'they control the up and side thrust grav(h) = -power(h) - thrust(h) 'of the bullet. up(h) = grav(h) 'I've seen lots of games that could END IF ' use this formula. GOSUB drawcan 'if you use it, at least tell me. shotx(h) = POINT(0) shoty(h) = POINT(1) - 1 shot(h) = 1 FOR l = 1 TO 1 i = 1500 - (l * 10) SOUND (i), 1 NEXT l END IF RETURN angright: GOSUB erasecan ang(h) = ang(h) - 5 IF ang(h) < -90 THEN ang(h) = -90 GOSUB drawcan RETURN angleft: GOSUB erasecan ang(h) = ang(h) + 5 IF ang(h) > 90 THEN ang(h) = 90 GOSUB drawcan RETURN