bastools/samples/destroyer.bas

188 lines
6.5 KiB
QBasic

' One-time initializations
10 gosub 50000: \
chargemax=5: \
dim chargex(chargemax),chargey(chargemax),chargeshape(chargemax),\
priorchargex(chargemax),priorchargey(chargemax),priorchargeshape(chargemax): \
ch=36:cv=37: \
charwidth=7:charheight=8: \
space=asc(" "):rubshape=95+charbase: \
waterline=40:shipy=waterline-3:chargestarty=waterline+2: \
goto 1000
' Search list of depth charges for open slot; if found, queue up the next depth charge!
20 for i=1 to chargemax: \
if chargex(i) then next i:return
30 chargex(i)=shipx: \
chargey(i)=chargestarty: \
chargeshape(i)=constdepthchargeshape: \
remainingcharges=remainingcharges-1: \
gosub 40: \
vtab 3:htab 37:qq=remainingcharges: \
return
' Display number in QQ zero-padded to 4 digits
40 a$="0000"+str$(qq): \
a$=mid$(a$,len(a$)-3)
' Display string at current HTAB,VTAB location. Note the erase done with the rub character; assumption is color is black!
50 ly=peek(cv)*charheight: \
lx=peek(ch)*charwidth
60 for c=1 to len(a$): \
ls=charbase+asc(mid$(a$,c,1))-space: \
draw rubshape at lx,ly: \
xdraw ls at lx,ly: \
lx=lx+charwidth: \
next c: \
return
' Update ALL states on the screen
90 vtab 1:htab 37:qq=hiscore:gosub 40: \
vtab 2:qq=score:gosub 40: \
vtab 3:qq=remainingcharges:gosub 40: \
return
' Game initialization
100 shipx=140:shipdirection=0:shipshape=constdestroyershape: \
score=0:remainingcharges=30:chargeindex=1
120 for i=1 to chargemax: \
chargex(i)=0: \
chargey(i)=0: \
chargeshape(i)=0: \
next i
130 subshape=0:subx=0:suby=0:subdirection=0
140 explosionshape=0:explosionx=0:explosiony=0
150 gosub 90
' Draw all active shapes (based on X coordinate)
200 xdraw shipshape at shipx,shipy: \
oldshipx=shipx:oldshipshape=shipshape
210 if subx then \
xdraw subshape at subx,suby: \
oldsubshape=subshape:oldsubx=subx:oldsuby=suby
220 priorchargex(chargeindex)=chargex(chargeindex): \
priorchargey(chargeindex)=chargey(chargeindex): \
priorchargeshape(chargeindex)=chargeshape(chargeindex)
230 if chargex(chargeindex) then \
xdraw chargeshape(chargeindex) at chargex(chargeindex),chargey(chargeindex)
240 if explosionx then \
xdraw explosionshape at explosionx,explosiony:zs=explosionshape:zx=explosionx:zy=explosiony
' Handle keyboard
300 keypress=peek(-16384): \
if keypress < 128 then 400
310 poke -16368,0
320 if keypress=136 then \
shipshape=constdestroyershape: \
shipdirection=shipdirection-1
330 if keypress=149 then \
shipshape=constdestroyershape+1: \
shipdirection=shipdirection+1
340 if shipdirection > 3 then shipdirection=3
350 if shipdirection < -3 then shipdirection=-3
360 if keypress=160 and remainingcharges > 0 then gosub 20
' Submarine. Only one at a time. If it doesn't exist, pick a random number to see if one shows up!
400 if not subx then 450
410 subx=subx+subdirection
420 if subx < 10 or subx > 270 then subshape=0:subx=0:suby=0:subdirection=0
430 goto 500
' Test for a new sub
450 rr=rnd(1):if rr < 0.10 then 480
460 if rr > 0.20 then 500
470 subx=10:suby=waterline+10+rnd(1)*80:subdirection=2:subshape=constsubshape+1:goto 500
480 subx=270:suby=waterline+10+rnd(1)*80:subdirection=-2:subshape=constsubshape
' Move the destroyer/ship
500 shipx=shipx+shipdirection
510 if shipx < 10 then shipx=10
520 if shipx > 270 then shipx=270
' Make the explosion all explody
550 if explosionshape then explosionshape=explosionshape+2:if explosionshape >= constdestroyershape then explosionx=0
' Move one of the depth charges
600 if not chargex(chargeindex) then 690
610 chargeshape(chargeindex)=chargeshape(chargeindex)+1: \
if chargeshape(chargeindex) > constdepthchargeshape+3 then \
chargeshape(chargeindex)=constdepthchargeshape
620 chargey(chargeindex)=chargey(chargeindex)+5: \
if chargey(chargeindex) > 155 then \
chargex(chargeindex)=0: \
chargey(chargeindex)=0: \
chargeshape(chargeindex)=0
' Setup for next depth charge
690 chargeindex=chargeindex+1: \
if chargeindex > chargemax then \
chargeindex = 1
' Erase shapes
700 if oldsubx then \
xdraw oldsubshape at oldsubx,oldsuby: \
a=oldsubx:oldsubx=0: \
if peek(234) then \
explosionshape=oldsubshape+2: \
explosionx=a: \
explosiony=oldsuby: \
subx=0: \
score=score+1: \
remainingcharges=remainingcharges+5: \
vtab 2:htab 37:qq=score:gosub 40: \
vtab 3:qq=remainingcharges:gosub 40
710 if priorchargex(chargeindex) then \
xdraw priorchargeshape(chargeindex) at priorchargex(chargeindex),priorchargey(chargeindex): \
if peek(234) then \
chargex(chargeindex)=0: \
chargey(chargeindex)=0: \
chargeshape(chargeindex)=0
720 if zx then xdraw zs at zx,explosiony:zx=0
730 xdraw oldshipshape at oldshipx,shipy
740 if remainingcharges > 0 then 200
' Stupidly, once we run out of charges, we immediately end the game :-/
' Check if a high score was set ...
800 if score > hiscore then hiscore = score
' Display the title screen!
1000 hgr:poke -16302,0
1010 hcolor=0: \
vtab 1:htab 1:a$="Destroyer!":gosub 50
1020 vtab 22:htab 4:a$="| Left, } Right, Spacebar to fire":gosub 50
1030 vtab 1:htab 28:a$="Hiscore:":gosub 50:vtab 2:a$="Score:":gosub 50:vtab 3:a$="Charges:":gosub 50:gosub 90
1050 hcolor=6: \
hplot 0,waterline to 279,waterline: \
hplot 0,159 to 279,159:hcolor=0
1060 ly=waterline+15: \
xdraw constdestroyershape at 45,ly+3: \
a$="Your destroyer":lx=70:gosub 60
1070 ly=ly+10: \
xdraw constsubshape at 45,ly+3: \
a$="Enemy submarine (1 point)":lx=70:gosub 60
1080 ly=ly+10:lx=40: \
for s=constdepthchargeshape to constdepthchargeshape+3: \
xdraw s at lx,ly+3: \
lx=lx+5: \
next s: \
a$="Depth charges (hit = +5!)":lx=70:gosub 60
1090 ly=ly+20:lx=40: \
a$="Demo code for 'bastools'":gosub 60
1100 ly=ly+10:lx=40: \
a$="Visit applecommander.github.io":gosub 60
1110 ly=ly+20:lx=40: \
a$="PRESS ANY KEY TO BEGIN!":gosub 60
1120 if peek(-16384)<128 then 1120
1130 poke -16368,0
1140 hcolor=0: \
for y=waterline+15 to 150: \
hplot 0,y to 279,y: \
next y
1150 goto 100
50000 $shape src="destroyer.st", \
poke=yes, \
init=yes, \
assign=(constsubshape="sub-left", \
constdestroyershape="ship-left", \
constdepthchargeshape="depthcharge-1", \
charbase="characters")