I posed a question on Facebook, asking what my next game for this competition should be. Among the replies, my friend and indie game developer Adam Rippon suggested a shmup" (shoot 'em up) (because "There's not enough shmups").
In the game, you control a ship at the left of the screen
(render as the characters "=>
"), which can move vertically
using Up and Down on a joystick, and shoot lasers towards the right side of the
screen using the joystick Fire button.
Enemies appear randomly on the right side of the screen and move left, towards you. If you crash into an enemy, you lose a life (you have 3). Shoot the enemies to destroy them and earn a point.
As the game progresses, the enemies appear more often. (The difficulty, based on your progress, starts at 0.0 and maxes out at 10.0.)
When you run out of lives, the game ends and your score ("SC
",
short for "score") and progress ("WV
", short for "wave"), are
shown at the top of the screen. Press Fire to start a new game.
I decided to use a large text mode, and use block memory movement of screen data to provide coarse scrolling. After writing a basic starfield that scrolled to the left, I began using some pre-calculated pointers (rather than doing the same math every frame), and variables-as-constants, to achieve fairly fast results.
Next came a ship, which moved vertically. Then enemies, which your ship would collide with. The laser was added next, but my initial attempt at having a screen-width trail which was erased at the end of the laser shot was failing.
I added sound effects and explosions — enemies as a
quick FOR
-loop when they're hit, and your own ship as an
ongoing explosion while the rest of the game continued (i.e., your exploding
ship keeps flying through space).
I went back and opted to have the laser erase itself as it shot across the screen. At this point, the game worked, but I decided to add one final
10 GRAPHICS 17:SC=DPEEK(88):SC1=SC+1:SC440=SC+440:SC420=SC+420:YSC=SC+220:Z479=479:Z19=19:Z20=20:SOUND 1,200,0,4:LV=3
GRAPHICS 0
-style) text window at the bottom
SC
SC1
SC440
SC420
YSC
; subtract 20 and the ship moves up a line, etc.
Z479
, Z19
and Z20
LV
)
100 POKE SC+Z19+RAND(23)*Z20,14:FOR I=SC TO SC440 STEP Z20:POKE I,%0:NEXT I:IF RAND(12-WV)=0:BSC=SC+Z19+RAND(22)*Z20
WV
), whether to add an enemy at the right edge of the screen, too. If so...
BSC
)
110 POKE BSC,74:POKE BSC+Z20,126:ENDIF :MOVE SC1,SC,Z479:IF EX=0:C=PEEK(YSC+1):DPOKE YSC,40669:S=PEEK(632):F=STRIG(%0)
*
on top, and a ^
on the bottom
>
") of our ship is at column 0, and will soon be redrawn at column 1. By checking what's at column 1 just before that, we can tell whether we crashed into an enemy.)
S
) and fire button (F
)
120 IF C<>%0 AND C<>14 THEN EX=30:LV=LV-%1:IF LV=%0 THEN ? #6;"SC:";PT;" WV:";WV:PAUSE 2:WHILE STRIG(%0):WEND :RUN
.
", 14)
EX
)
LV
)
SC
) and progress/wave (WV
)
130 IF S=14 AND YSC>SC:YSC=YSC-Z20:ENDIF :IF S=13 AND YSC<SC420 THEN YSC=YSC+Z20
140 IF F=%0:FOR X=2 TO 18 STEP 2:LX=X:C=DPEEK(YSC+X):IF C<>%0 AND C<>14 AND C<>3584 AND C<>3598:GOSUB 1000:ENDIF
X
)
LX
); it may get altered (to short-circuit us out of this FOR
-loop), if we hit an enemy (so that you only hit the first one, not all enemies on the row)
C
)
150 DPOKE YSC+LX,65535:DPOKE YSC+LX-2,%0:NEXT X:DPOKE YSC+LX,%0:ENDIF :ELSE :DPOKE YSC,RAND(65536):EX=EX-1
LX
)
LX-2
)
EX
)
999 SOUND 0,R,12,EX/%2:ENDIF :R=PEEK(53770):DPOKE 708,(R&15)+R*256:IF WV<10:WV=WV+0.01:ENDIF :GOTO 100
R
is actually set later, outside of this
IF/ELSE/ENDIF
, but since it's set every iteration of the
main loop, it's fine to just use it)
RANDOM
register and store it in
a variable (R
)
COLOR0
, used for the stars,
to a random (R
) shade (luminence) of white,
and COLOR1
, used for the enemies, to a totally random color
(hue+luminence)
WV
) of '10',
add a little bit to it until we do
1000 ESC1=YSC+X:X=18:ESC2=ESC1:IF YSC>SC:ESC2=ESC1-Z20:ENDIF :FOR I=%0 TO 7:DPOKE ESC1,I*257:DPOKE ESC1+Z20,I*257
ESC1
)
ESC2
to the same as ESC1
IF/ENDIF
, is less code than having a proper IF/ELSE/ENDIF
)
ESC2
to the spot one line aboveI
)...
ESC1
)
ESC2+Z20
)
1010 DPOKE ESC2,I*257:SOUND %0,PEEK(53770),8,14-I*%2:NEXT I:DPOKE ESC1,%0:DPOKE ESC1+Z20,%0:DPOKE ESC2,%0:PT=PT+1:RETURN
ESC2
)
DOS.SYS
, DUP.SYS
)
TBASIC.AR0
)
AUTORUN.BAS
;
except for the filename , same as SHMUP.TBS
stand-alone file, above)
Bill Kendrick, 2014,
nbs@sonic.net,
New Breed Software
Other games I wrote for NOMAM 2014