QBASIC GAME : THE HORDE
DEFINT A-Z
DECLARE SUB story ()
DECLARE SUB youdie ()
DECLARE SUB gprint (x%, y%, culler%, text$)
DECLARE SUB setpal (reg%, RED%, GREEN%, BLUE%)
DECLARE SUB drawyou (angle%)
SCREEN 7, , 1, 1'Screen 7 for Page Flipping... Less colors than could be wanted, but hey, you can't have everything
PRINT "The Horde 1.43 Final is Initalizing...."
PRINT "----Prepare for immersion----"
RANDOMIZE TIMER
PRINT "Creating and Initalizing Starfield"
CONST numstar = 20 'a lot=slower :)
TYPE star
x AS INTEGER
y AS INTEGER
END TYPE
DIM SHARED stars(1 TO numstar) AS star 'few for speed
FOR a = 1 TO numstar
stars(a).x = INT(RND * 320) + 1
stars(a).y = INT(RND * 200) + 1
NEXT a
PRINT "Drawing and Initalizing You"
DIM youu(1 TO 80)
DIM youd(1 TO 80)
DIM youl(1 TO 80)
DIM your(1 TO 80)
DIM youul(1 TO 80)
DIM youdl(1 TO 80)
DIM youur(1 TO 80)
DIM youdr(1 TO 80)
drawyou (270) 'up
GET (153, 93)-(167, 107), youu
LINE (153, 93)-(167, 107), 0, BF
drawyou (90) 'down
GET (153, 93)-(167, 107), youd
LINE (153, 93)-(167, 107), 0, BF
drawyou (180)'right
GET (153, 93)-(167, 107), your
LINE (153, 93)-(167, 107), 0, BF
drawyou (0)' left
GET (153, 93)-(167, 107), youl
LINE (153, 93)-(167, 107), 0, BF
drawyou (45) ' down-left
GET (153, 93)-(167, 107), youdl
LINE (153, 93)-(167, 107), 0, BF
drawyou (315) ' up-left
GET (153, 93)-(167, 107), youul
LINE (153, 93)-(167, 107), 0, BF
drawyou (225) 'up right
GET (153, 93)-(167, 107), youur
LINE (153, 93)-(167, 107), 0, BF
drawyou (135) 'up left
GET (153, 93)-(167, 107), youdr
LINE (152, 93)-(169, 107), 0, BF
youpow = 80
maxyoupow = 80
PRINT "Drawing and Initalizing Aliens"
'----------------------
DIM SHARED enemystr
DIM SHARED maxenemies AS INTEGER
maxenemies = 5
TYPE enemy
x AS INTEGER
y AS INTEGER
pow AS INTEGER
xv AS INTEGER
yv AS INTEGER
alive AS INTEGER '0=no 1=yes
END TYPE
DIM ali(1 TO maxenemies) AS enemy
DRAW "ta0"
DIM alien(1 TO 180)
PSET (160, 100), 8
DRAW "u8 r8 d8 l8"
FOR B = 1 TO 360 STEP 45
PSET (164, 96), 4
DRAW "TA=" + VARPTR$(B)
DRAW "u4"
NEXT B
PSET (163, 95), 3: PSET (164, 95), 3: PSET (165, 95), 3
PSET (163, 96), 3: PSET (164, 96), 3: PSET (165, 96), 3
PSET (163, 97), 3: PSET (164, 97), 3: PSET (165, 97), 3
'LINE (158, 90)-(170, 102), 8, B
GET (158, 90)-(170, 102), alien
LINE (158, 90)-(170, 102), 0, BF
PRINT "Initalizing Guns"
'----------------------
TYPE shot
x AS INTEGER
y AS INTEGER
dirx AS INTEGER
diry AS INTEGER
who AS INTEGER '1=Alien 2=You (so your shots don't hit you)
alive AS INTEGER
END TYPE
CONST maxshot = 14
CONST maxfiredelay = 4
firedelay = 0
DIM shots(1 TO maxshot) AS shot
DIM shotpic(18) AS INTEGER
x = 160
y = 100
PSET (x, y), 14
PSET (x - 1, y), 12
PSET (x + 1, y), 12
PSET (x, y + 1), 12
PSET (x, y - 1), 12
GET (159, 99)-(161, 101), shotpic
PRINT "Initalizing Explosions"
TYPE xplo
x AS INTEGER
y AS INTEGER
stage AS INTEGER
END TYPE
DIM SHARED maxplo
maxplo = 3
DIM xplosions(1 TO maxplo) AS xplo
PRINT "Initalizing Palettes"
setpal 1, 30, 30, 30 'Your hull
setpal 6, 63, 0, 0 'your laser
setpal 3, 63, 63, 0 'enemy lights --these do a fadecycle-
fadecol = 63
PRINT "Initalizing Globals"
DIM SHARED yourhealth AS INTEGER
DIM SHARED maxhealth AS INTEGER
DIM SHARED level AS INTEGER
DIM SHARED bossstr AS INTEGER
DIM SHARED gundamage AS INTEGER
DIM SHARED viewpage AS INTEGER
DIM SHARED drawpage AS INTEGER
DIM SHARED youdir
DIM SHARED shotsfired AS LONG
DIM SHARED hits AS LONG
'youdir=1=up 2=down 3=left 4=right 5=upleft 6=upright 7=downleft 8=downright
youdir = 2
viewpage = 0 'for page flipping-what you see
drawpage = 1 'for page flipping-what is being drawn
maxhealth = 20
yourhealth = maxhealth
level = 1
bossstr = 40
gundamage = 5
DIM SHARED stardirx
DIM SHARED stardiry
stardirx = 0
stardiry = -2
DIM SHARED shotdirx
DIM SHARED shotdiry
shotdirx = 0
shotdiry = 3
PRINT "Creating Background Plane" 'NOT USED-FLICKERS TERRIBLY
SCREEN 7, , 2, 0
FOR a = 1 TO 5
x = INT(RND * 320) + 1
y = INT(RND * 200) + 1
PSET (x, y), 15
PSET (x - 1, y), 8
PSET (x + 1, y), 8
PSET (x, y + 1), 8
PSET (x, y - 1), 8
NEXT a
SCREEN 7, , 0, 0
PRINT "Initalizing Sine/Cosine Tables"
DIM sinelook(0 TO 360)
DIM cosinelook(0 TO 360)
DIM pi AS DOUBLE
pi = 3.1415927#
FOR a = 0 TO 360
sinelook(a) = SIN(a * (pi / 180)) 'Velocity Tables
cosinelook(a) = COS(a * (pi / 180)) 'Velocity Tables
NEXT a
PRINT "Initalization Complete"
story 'duhhh
CLS
youdir = 2
fadecoldir = -2
fadecol = 60
DO 'main game loop
SCREEN 7, , drawpage, viewpage 'draw the page drawn before!
LINE (0, 0)-(320, 200), 0, BF 'MUCH better than CLS, Less/No Flicker!
fadecol = fadecol + fadecoldir
IF fadecol < 10 OR fadecol > 60 THEN
fadecoldir = -fadecoldir
END IF
CALL setpal(3, fadecol, fadecol, 0)
LINE (1, 200)-(1, 200 - youpow), 12
LINE (2, 200)-(2, 200 - firedelay * 4), 15 'Usually not seen :)
IF youpow <= 0 THEN CALL youdie 'hmmm I wonder :)
FOR a = 1 TO numstar
stars(a).x = stars(a).x + stardirx
stars(a).y = stars(a).y + stardiry
IF stars(a).x < 0 THEN stars(a).x = 320
IF stars(a).x > 320 THEN stars(a).x = 0
IF stars(a).y < 0 THEN stars(a).y = 200
IF stars(a).y > 200 THEN stars(a).y = 0
PSET (stars(a).x, stars(a).y), 15
NEXT a
FOR a = 1 TO maxenemies
IF ali(a).alive = 0 THEN
'BEEP
where = INT(RND * 4) + 1
SELECT CASE where 'what wall
CASE 1
x = 1
y = INT(RND * 200) + 1
xv = INT(RND * 2) + 1
yv = -2 + INT(RND * 4) + 1
CASE 2
x = 320
y = INT(RND * 200) + 1
xv = INT(RND * 2) + 1
yv = -2 + INT(RND * 4) + 1
CASE 3
x = INT(RND * 320) + 1
y = 1
xv = -2 + INT(RND * 4) + 1
yv = INT(RND * 2) + 1
CASE 4
x = INT(RND * 320) + 1
y = 200
xv = -2 + INT(RND * 4) + 1
yv = -INT(RND * 2) + 1
CASE ELSE 'you shouldn't be here :)
END SELECT
'put them values into the clicker..er..array... :)
ali(a).x = x
ali(a).y = y
ali(a).xv = xv
ali(a).yv = yv
ali(a).alive = 1
END IF
NEXT a
'aliens added, now draw 'em
'----------------------
FOR a = 1 TO maxenemies
IF ali(a).alive = 1 THEN 'alive
'BEEP
'adding stardir is not exactly the best way but it works :)
'this sorta moves the aliens with the stars...not perfect :)
ali(a).x = ali(a).x + stardirx / 2
ali(a).y = ali(a).y + stardiry / 2
ali(a).x = ali(a).x + ali(a).xv
ali(a).y = ali(a).y + ali(a).yv
'bound check...whoda thunk it?
IF ali(a).x > 300 OR ali(a).x < 1 THEN
ali(a).alive = 0
END IF
IF ali(a).y > 180 OR ali(a).y < 1 THEN
ali(a).alive = 0
END IF
IF ali(a).alive = 1 THEN 'still alive
PUT (ali(a).x, ali(a).y), alien, PSET 'what's it look like? :)
END IF
END IF
NEXT a
'do shots
'======================
'Shots are actually started in the iteration before :)
firedelay = firedelay - 1 'delay
IF firedelay < 0 THEN firedelay = 0 'if there's a delay make new shots not there :)
'IF firedelay > 0 THEN newshot = 0 'no new shots if firedelay isn't 0
IF newshot = 1 THEN
'call a new shot!
shotsfired = shotsfired + 1 'I don't think I use this
IF firedelay = 0 THEN
FOR test = 1 TO maxshot
IF shots(test).alive = 0 THEN
IF newshot = 1 THEN 'Don't fill all shot spots up!
'It might be kewl like that...one huge particle shot :)
'constantly hitting things :)
'free shot space
newshot = 0 'Stop adding more shotz
shots(test).x = 166 'the values are set to start in YOUR CENTER! :)
shots(test).y = 106 'that's why the SHOTS.WHO is needed :)
shots(test).who = 2 '2=you 1=alien (no aliens shots as of v1.32)
'shotdir? is set in the movement :)
shots(test).dirx = shotdirx 'quick and dirty...gotta love it :)
shots(test).diry = shotdiry 'shots go somewhat faster than the stars
shots(test).alive = 1
END IF
END IF
NEXT test
firedelay = maxfiredelay 'firedelay time!
ELSEIF firedelay > 0 THEN
newshot = 0 'firedelay not 0 yet
END IF
END IF
FOR doshot = 1 TO maxshot
still = 1';still alive...used in code :)
IF shots(doshot).alive = 1 THEN 'a good shot we have here
'I like ta' movit movit...I like ta' MOV it MOV it, I like ta' MOV IT!
'da dada duh duh dun dunh oohps I'm typing... :)
shots(doshot).x = shots(doshot).x + shots(doshot).dirx
shots(doshot).y = shots(doshot).y + shots(doshot).diry
'bound check!..without this the PUTs crash
IF shots(doshot).x < 4 OR shots(doshot).x > 314 THEN
shots(doshot).alive = 0 'kill the shot
still = 0 'should we STILL display it?
END IF
IF shots(doshot).y < 4 OR shots(doshot).y > 196 THEN
shots(doshot).alive = 0 'kill the shot
still = 0 'should we STILL display it?
END IF
'draw the shot!
IF still = 1 THEN 'if the shot didn't run offbounds
PUT (shots(doshot).x, shots(doshot).y), shotpic, PSET
END IF
END IF
'now to detect collisions :)
'----------------------
'surprisingly I got this part working in about 10 minutes :)
'this part is horrendously nested... sorry :)
FOR B = 1 TO maxenemies
IF shots(doshot).x >= ali(B).x AND shots(doshot).x < ali(B).x + 12 THEN
IF shots(doshot).y >= ali(B).y AND shots(doshot).y < ali(B).y + 12 THEN
'Well, I do declayah: You made a hit!
ali(B).alive = 0 'alien is busted
shots(doshot).alive = 0 'shot is busted: no multi-hits :) (that would actually kick though)
'add an explosion
x = ali(B).x
y = ali(B).y
hits = hits + 1
GOSUB newxplo 'Shudder: -gosub-.. look at Wormhole and many other games :)
END IF
END IF
NEXT B
NEXT doshot
FOR a = 1 TO maxenemies
'this part was hideous to code and still isn't perfect :)
IF ali(a).x >= 160 AND ali(a).x <= 170 OR ali(a).x + 12 >= 160 AND ali(a).x + 12 <= 170 THEN
IF ali(a).y >= 100 AND ali(a).y <= 110 OR ali(a).y + 12 >= 100 AND ali(a).y + 12 <= 110 THEN
'BEEP
'POW-you're hit!
youpow = youpow - 5 'ouch
IF ali(a).xv < 0 THEN ali(a).xv = ali(a).xv + 4
IF ali(a).xv > 0 THEN ali(a).xv = ali(a).xv - 4
IF ali(a).yv < 0 THEN ali(a).xv = ali(a).yv + 4
IF ali(a).yv > 0 THEN ali(a).xv = ali(a).yv - 4
ali(a).xv = -(ali(a).xv + 2)'deflected -- actually, they bounce inside you
ali(a).yv = -(ali(a).yv + 2)'deflected -- and hurt you more (sometimes)
END IF
END IF
NEXT a
v$ = UCASE$(RIGHT$(INKEY$, 1))
SELECT CASE v$
CASE "D" 'die -- debug key/alternate quit button :)
youpow = 0
CASE " " 'space for fire
'Fuh-HIRE!
newshot = 1
CASE CHR$(27)
END
CASE "P"
stardirx = 0
stardiry = -2
shotdirx = 0
shotdiry = 3
youdir = 2
CASE "H"
stardirx = 0
stardiry = 2
shotdirx = 0
shotdiry = -3
youdir = 1
CASE "M"
stardirx = -2
stardiry = 0
shotdirx = 3
shotdiry = 0
youdir = 4
CASE "K"
youdir = 3
stardirx = 2
stardiry = 0
shotdirx = -3
shotdiry = 0
CASE "2"
youdir = 2
stardirx = 0
stardiry = -2
shotdirx = 0
shotdiry = 3
CASE "8"
youdir = 1
stardirx = 0
stardiry = 2
shotdirx = 0
shotdiry = -3
CASE "6"
youdir = 4
stardirx = -2
stardiry = 0
shotdirx = 3
shotdiry = 0
CASE "4"
youdir = 3
stardirx = 2
stardiry = 0
shotdirx = -3
shotdiry = 0
CASE "3"
youdir = 8
stardirx = -2
stardiry = -2
shotdirx = 3
shotdiry = 3
CASE "9"
youdir = 6
stardirx = -2
stardiry = 2
shotdirx = 3
shotdiry = -3
CASE "7"
youdir = 5
stardirx = 2
stardiry = 2
shotdirx = -3
shotdiry = -3
CASE "1"
youdir = 7
stardirx = 2
stardiry = -2
shotdirx = -3
shotdiry = 3
END SELECT
FOR a = 1 TO maxplo 'only 3 explosions: for speed and you wouldn't notice
IF xplosions(a).x <> 0 THEN 'crazy results without this :)
xplosions(a).x = xplosions(a).x + stardiry 'this dosn't work right :)
xplosions(a).y = xplosions(a).y + stardiry 'who cares? looks good :)
'actually; doesn't work like I wanted it to
x = xplosions(a).x
y = xplosions(a).y
s = xplosions(a).stage 'copy these variables for less array accessing
CIRCLE (x, y), s, 14 'expanding yellow circle
CIRCLE (x, y), 10, 6, , , s 'shrinking horizontaly circle
FOR B = 1 TO 15 'little particles-hard to notice at first but you can "sense" 'em :)
x2 = -6 + INT(RND * 12) + 1
y2 = -6 + INT(RND * 12) + 1
PSET (x + x2, y + y2), 15
NEXT B
xplosions(a).stage = xplosions(a).stage + 1 'increase
IF xplosions(a).stage = 10 THEN xplosions(a).x = 0 'if it's too high, cancel!
END IF
NEXT a
'do you...drawing anyway :)(
'======================
'youdir=1=up 2=down 3=left 4=right 5=upleft 6=upright 7=downleft 8=downright
SELECT CASE youdir 'Maybe not the fastest code but easiest to modify & understand
CASE 1 'I picked good names for the GET arrays, try to figure them out :)
PUT (160, 100), youu, PSET
CASE 2
PUT (160, 100), youd, PSET
CASE 3
PUT (160, 100), youl, PSET
CASE 4
PUT (160, 100), your, PSET
CASE 5
PUT (160, 100), youul, PSET
CASE 6
PUT (160, 100), youur, PSET
CASE 7
PUT (160, 100), youdl, PSET
CASE 8
PUT (160, 100), youdr, PSET
END SELECT
WAIT &H3DA, 8 'keep same max speed
WAIT &H3DA, 8, 8 'but I never mentioned MINIMUM speed :)
SWAP drawpage, viewpage 'flip the draw/view pointers
LOOP 'and start all this over again!
END
newxplo:
yes = 0
FOR a = 1 TO maxplo
IF xplosions(a).x = 0 AND yes = 0 THEN 'alive
yes = 1
xplosions(a).x = x 'X and Y were set in the shot collision part
xplosions(a).y = y
xplosions(a).stage = 1
END IF
NEXT a
RETURN
DEFSNG A-Z
SUB drawyou (angle%)
PSET (160, 100), 0
DRAW "TA=" + VARPTR$(angle%)
DRAW "bu2c1l5g2f2r5d3e3c4u4bl1c5d4bu5c1h2d3bd1bl3u0d2bl1bl3bu1c6l1 "
END SUB
DEFINT A-Z
SUB gprint (x, y, culler, text$)
DEF SEG = &HFFA6 ' ROM segment for character shape table
XX% = x
FOR Char% = 1 TO LEN(text$)
Addr% = 8 * ASC(MID$(text$, Char%, 1)) + 14
FOR Ln% = 0 TO 7
LineFormat% = CVI(CHR$(0) + CHR$(PEEK(Addr% + Ln%)))
YY% = y + Ln%
LINE (XX%, YY%)-(XX% + 7, YY%), culler, , LineFormat%
NEXT
XX% = XX% + 8
NEXT
DEF SEG
END SUB
SUB setpal (reg%, RED%, GREEN%, BLUE%)
OUT &H3C8, reg%
OUT &3C9, RED%
OUT &H3C9, GREEN%
OUT &H3C9, BLUE%
END SUB
SUB story
LOCATE 24
PRINT "It has been 2 years since the"
PRINT "last of the aliens from the "
PRINT "wormhole were repelled."
PRINT "We thought it was safe. But,"
PRINT "two weeks ago a message was "
PRINT "recived from a space drone"
PRINT "that an alien fleet was found."
PRINT "The aliens are back."
PRINT "This time you're in a specially"
PRINT "fitted Scout Runner with plasma"
PRINT "particle guns."
PRINT "--press any key to continue--"
WHILE INKEY$ = "": WEND
PRINT "The guns require a breif cooldown"
PRINT "period between shots, during which"
PRINT "your only defense is your hull armor."
PRINT "You can withstand about 10-15"
PRINT "collisions, and that's about it."
PRINT "The aliens are smart and will"
PRINT "run at high speed to evade your"
PRINT "shots once you hit them."
PRINT "For now the enemy ships are unarmed,"
PRINT "but the constant stream of them is"
PRINT "more than dangerous enough."
PRINT "Prepare for immersion in...."
PRINT
PRINT
COLOR 14: PRINT " The Horde"
COLOR 15: PRINT "--press any key to continue--"
WHILE INKEY$ = "": WEND
PRINT "Instructions:"
PRINT "Press SPACE to fire"
PRINT "the numeric keypad"
PRINT "allows diagonal directions as"
PRINT "well as regular directions, and"
PRINT "the regular keypad does the "
PRINT "obvious directions."
PRINT "Press ESC to quit, or D to "
PRINT "kill yourself and quit."
PRINT "The red bar on the right is"
PRINT "hull strength, and the gun"
PRINT "cooling level is shown with "
PRINT "the white bar, which vanishes"
PRINT "when you can fire again."
PRINT "Oh yeah, the guns have a"
PRINT "force beam to keep them"
PRINT "level with you, no matter what"
PRINT "direction you're facing."
COLOR 15: PRINT "--press any key to play--"
WHILE INKEY$ = "": WEND
END SUB
SUB youdie
CALL setpal(1, 63, 63, 63)
CALL setpal(2, 63, 63, 0)
SCREEN 7, , 0, 0
LINE (0, 0)-(320, 200), 1, BF
c = 63
FOR a = 0 TO 200 STEP 2
CALL setpal(1, c, c, c)
c = c - 1
IF c < 0 THEN c = 0
CIRCLE (160, 100), a, 2
CIRCLE (161, 101), a, 2
CIRCLE (159, 101), a, 2
CIRCLE (159, 100), a, 2
CIRCLE (161, 100), a, 2
WAIT &H3DA, 8
WAIT &H3DA, 8, 8
NEXT a
CLS
LOCATE 12, 10
PRINT "You have failed...."
PRINT "Shots fired:"; shotsfired
PRINT "Kills------:"; hits
PRINT "Misses-----:"; shotsfired - hits
IF shotsfired = 0 THEN shotsfired = 1
IF hits = 0 THEN hits = 1
'PRINT "Accuracy---:"; INT(shotsfired); "%" 'not sure how to show accuracy
END
END SUB
0 Comments