home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
TCE Demo 2
/
TCE_DEMO_CD2.iso
/
demo_cd_.2
/
mags
/
stosser
/
stoser05.arj
/
stoser05.msa
/
A
/
4.PNE
< prev
next >
Wrap
Text File
|
1987-04-22
|
12KB
|
418 lines
The Missing Link Tutorial
By Billy Allan of Top Notch
Part One - A Basic Shoot-Em-Up.
So, you've got STOS, got The Missing
Link (where's that sound of dripping
water coming from?) and got an idea for
a game. Great. Unfortunately after this
usually comes the more tricky part -
writing the bloody thing!
Well, over the next few issues I'll be
taking you through, stage by stage, to
write a complete shoot-em-up. I am
assuming that everyone reading this has
written a game or a few programs in STOS
already and generally knows all the
basic stuff (what variables are and the
rest of it). I suppose it's aimed at
the, what "proper" publications call,
intermediate to advanced STOS programmer
In this first section I'll just go
through a listing of a little shoot-em-
up I knocked together which I'll be
using as a base from which the future
articles will be built upon.
The game, as stands, has 10 aliens with
one bullet each, a vertically scrolling
landscape in the background and a main
player sprite with 4 bullets. It also
has collision detection between sprites,
a lives system, a score counter and some
sound effects.
- - - -
20 if length(1)=0 then load "gamebob.mbk
",1
30 if length(5)=0 then load "backblk.mbk
",5
40 if length(6)=0 then load "map.mbk",6
50 if length(10)=0 then reserve as data
10,10000 : bload "awesome1.mus",10
Lines 20-50 load in the data files
needed by the game. I always use the "if
length(x)=0 then..." to load in data
files. It saves a lot of time as the
file is only loaded once and then is
automatically skipped every time you run
the game after that. When you save the
source you can just erase all of the
memory banks and when you run it next
time they'll automatically load back in.
60 dim BX(9),BY(9),BON(9),BIMG(9),BDR(9)
70 dim BBX(9),BBY(9),BBON(9),BBIMG(9)
80 dim BULX(4),BULY(4),BULON(4),BULIMG
(4)
Set up the arrays for the aliens, alien
bullets and player bullets respectively.
180 S1=start(1) : S10=start(10) : S5=
start(5) : S6=start(6)
Set up pointers to each of the used
memory banks as using Sx is faster than
START(x).
200 many bob 0,0,320,192,0,0,0,0,0,1
210 bob 0,0,320,192,0,1
220 landscape 0,0,320,192,0,1 : MY=1408
: SCR=0 : LIV=5
Set the clipping for each command which
is used. Then set up three variables. MY
is the Map Y, SCR is the SCoRe and LIV
is the number of LIVes.
230 D=palt(S1) : wait vbl
Get the palette. Notice the WAIT VBL -
this is because the PALT command only
changes the palette at the next VBL
(move.l #palt,$45a.w actually).
240 CNT=0 : SCNT=0 : SFX=0
245 X=160 : Y=160 : IMG=0 : AC=0 : DED=
false
Set up the variables which *will* be
re-initialised every time the player
dies. CNT is a counter to give a pause
between the players' bullets, SCNT is a
counter to give pauses between sound
effects, SFX is the music number of the
sound effect to play, X and Y are the
players X and Y co-ordinates, IMG is the
players image number (in the BOB bank),
AC is a flag for whether the player is
accelerating and DED is is a flag for
the player dying.
246 for T=0 to 9
247 BX(T)=rnd(144)*2 : BY(T)=-rnd(100)
248 BON(T)=1 : BIMG(T)=7 : BDR(T)=rnd(1)
*2 : if BDR(T)=0 then BDR(T)=-2
249 BBX(T)=-32 : BBY(T)=-32 : BBON(T)=0
: BBIMG(T)=12 : next T
This sets up the parameters for the
baddies and their bullets.
250 for T=0 to 4
251 BULX(T)=-32 : BULY(T)=-32 : BULON(T)
=0 : BULIMG(T)=6
252 next T
Set up the players bullets.
>>>> Now the main loop <<<<
280 landscape logic,S5,S6,0,MY,0
Draw the background.
285 T=string(SCR) : text logic,0,T,0,24
286 T=string(LIV) : text logic,0,T,20,24
Display the score and number of lives left.
290 dec MY : if MY<0 then MY=1408
Move the map's Y up and wrap it at zero.
300 many bob logic,S1,varptr(BIMG(0)),
varptr(BX(0)),varptr(BY(0)),varptr(BON
(0)),0,0,9,0
310 many bob logic,S1,varptr(BBIMG(0)),
varptr(BBX(0)),varptr(BBY(0)),varptr
(BBON(0)),0,0,9,0
320 many bob logic,S1,varptr(BULIMG(0)),
varptr(BULX(0)),varptr(BULY(0)),varptr
(BULON(0)),0,0,3,0
330 bob logic,S1,IMG+AC,X,Y,0
Draw all of the sprites. Notice in line
330 the IMG+AC. The way the players ship
is stored is: Left/left+engine flames
(EF); Centre/centre+EF; Right/right+EF.
This means that I only need to set the
AC var to 1 to get the correct image for
the accelerated rather than usually
doing something like "if jup then IMG=6"
or whatever. I really ought to have set
up pointer for each of the arrays
(something like VBON=varptr(BON(0)))
where I set up S1, S5 etc., but I
couldn't be bothered.
340 for T=0 to 9
350 if BON(T)=0 then BX(T)=rnd(144)*2 :
BY(T)=-rnd(50) : BON(T)=1 : BIMG(T)=7
: goto 400
360 if BIMG(T)=7 then BX(T)=BX(T)+BDR(T)
: if BX(T)>286 or BX(T)<2 then BDR(T)=
-BDR(T)
370 BY(T)=BY(T)+2 : if BY(T)>200 then BY
(T)=-rnd(50)
380 if BBON(T)=0 and BX(T) mod 16=0 then
inc BIMG(T) : if BIMG(T)>11 then BIMG
(T)=7 : BBON(T)=1 : BBX(T)=BX(T)+12 :
BBY(T)=BY(T)+24 : if SCNT=0 then SFX=5
: SCNT=2
390 if BBON(T)=1 then BBY(T)=BBY(T)+4 :
if BBY(T)>200 then BBY(T)=-32 : BBON
(T)=0
400 next T
This is the control loop for the
baddies and their bullets. Line 350
checks if the baddie is off (BON=0) and
sets up new parameters for it if it is,
then skips to the end of the loop. Line
360 checks to see if the baddie is *not*
firing (BIMG=7). If it not firing then
it is moved accross the screen. Line 370
moves the baddie down the screen by two
pixels and wraps it at 200. Line 380
checks if the baddies bullet is turned
off (BBON=0) and it is on a 16-pixel
boundary (BX mod 16=0). If so it anim-
ates the baddie sprite until its image
reaches 11, then it fires a bullet. Line
390 checks if the bullet is on (BBON=1)
then it moves the bullet down the screen
and turns it off if it reaches the
bottom of the screen.
410 for T=0 to 3 : if BULON(T)=0 then
goto 450
420 BULY(T)=BULY(T)-6 : if BULY(T)<0
then BULON(T)=0
430 R=many overlap(BULX(T),BULY(T),
varptr(BX(0)),varptr(BY(0)),32,8,32,16
,varptr(BON(0)),varptr(BBON(0)),0,0,9)
440 if R>0 then BULON(T)=0 : if SCNT=0
or SFX=5 then SFX=8 : SCNT=5 : SCR=SCR
+R*10
450 next T
This is the loop for the players
bullets. Line 410 checks if the bullet
is off (BULON=0) and skips the loop if
it is. Line 420 moves the bullet up the
screen and turns it off it it hits the
top of the screen. Line 430 does the
collision detection between the players
bullets and the baddie ships. Line 440
turns off the bullet if it collided with
anything and sets the sound effect vari-
able to 8 if the SCNT vcounter is zero
or the current sound effect is 5 (ie,
baddie firing noise). It then adds some
points onto the score.
451 R=many overlap(X,Y,varptr(BBX(0)),
varptr(BBY(0)),32,28,4,4,varptr(BBON
(0)),varptr(BBON(0)),0,0,9)
452 if R>0 then DED=true : dec LIV
453 R=many overlap(X,Y,varptr(BX(0)),
varptr(BY(0)),32,28,32,16,varptr(BON
(0)),varptr(BBON(0)),0,0,9)
454 if R>0 then DED=true : dec LIV
Line 451-454 do the collisions between
the baddies, baddie bullets and the
player. If the player hits any of them
then the DED flag is set and the lives
are decreased.
460 if not(jleft) and not(jright) then
IMG=2
470 if jleft and X>0 then X=X-4 : IMG=0
480 if jright and X<288 then X=X+4 : IMG
=4
490 OY=Y : if jup and Y>100 then Y=Y-4
500 if jdown and Y<160 then Y=Y+4
510 if Y<>OY then AC=1 else AC=0
520 if fire+CNT=-1 then gosub 620
The player controls. Line 460 checks to
see if neither left or right was pressed
and sets the players image to the
"normal" position if so (2). Line 470-
480 moves left or right and sets the
image number. Line 490-500 check if the
ship is moving up or down. Notice that
I've stored the old Y on OY. This is to
be checked in line 510 against the
current Y to see if any vertical move-
ment occured, and if so the acceleration
flag (AC) is set. Line 520 checks if
fire was pressed and the CNT counter is
0 (therefore fire+CNT would equal -1, ie
fire=TRUE and CNT=0) and jumps to the
FIRE subroutine if so.
530 if CNT>0 then dec CNT
540 if SFX>0 then musplay S10,SFX,6 :
SFX=0
550 if SCNT>0 then dec SCNT
Lines 530+550 decrease the two game
counters. Line 540 plays the sound
effect if the sound effect variable
(SFX) is set.
560 screen swap : wait vbl
Do the screen swap.
570 if inkey$<>" " and not(DED) then
goto 280
Loop back to the start if space wasn't
pressed and the DED flag isn't set.
575 if DED then fade 3 : for T=1 to 28 :
wait vbl : next T : wipe logic : wipe
physic : if LIV>-1 then goto 230
580 musplay 0,0,0 : wait vbl : default :
end
Line 575 checks if the player is DEaD,
and fades to black if so. If it then
finds that the lives are still valid
(>=0) then it loops back to the initial-
isation section. Line 580 turns off the
music and exits.
>>>> The FIRE routine <<<<
620 Q=0 : while BULON(Q)=1 and Q<4 : inc
Q : wend
630 if Q=4 then return
640 if SCNT=0 and SFX<>5 then SFX=4 :
SCNT=3
650 BULX(Q)=X : BULY(Q)=Y : BULON(Q)=1 :
CNT=5 : return
This is my usual multi-fire routine.
Line 620 goes through the list of bullet
status flags until it either finds that
one is clear or it reaches the end of
the array. Line 630 returns back to the
main loop if the end of the array was
reached. Line 640 sets the fire sound
effect if the counter is zero and the
sound effect doesn't equal 5 (baddie
fire). Line 650 sets up the bullets par-
ameters and returns. Note that CNT is
set to 5. This means that the player
cannot fire until the main loop has been
executed a further 5 times.
- - - -
Well, I should think that's about as
clear as the script for Twin Peaks now,
so I'll bore you with some of the
general features of the program.
The first thing to notice is the
general structure of the main loop. The
graphics are drawn and *then* they are
moved. I find that this is usually the
easiest way of doing things, but I'm
sure there are just as many who do
things the opposite way (and probably
some who do a mixture of both... The
catflaps of the programming world...).
Next, you may be wondering why the
baddies stop moving horizontally when
they are firing, and indeed, why they
only fire when they hit a sixteen bound-
ary. This is a memory saving technique,
which although has fairly limited uses,
can be very useful when things get
tight. In the MAKE program I have only
made up one image for each frame of
animation of the baddie ship firing,
where as the ship normally has 4 images.
This means that I have saved 3 * the-
number-of-frames images. The drawback
is, of course, that the sprite can only
be displayed on a 16 pixel boundary.
It's always worth thinking on ways to
save memory by cutting out unneeded
images, especially if you're tight on
memory or disk space. (There is another
side effect in this particular case. As
BOBs on a sixeteen boundary are drawn
more quickly (16 pixels lees are drawn
on the right side of the image) then
this offsets the decrease in speed
caused by the animating sprite becoming
bigger in the Y axis.)
The next thing to notice is the use of
the two counters - CNT and SCNT. After
writing games for some time I've found
that these are the most convenient way
of adding a delay to the firing and
sound effects. SCNT is more involved as
new sound effects can only be started if
it is zero and if a sound effect with a
higher priority has not already been
started. The counter is also set to dif-
ferent lengths for the different sound
effects.
Other than that, I don't think there's
much to say about it really. The source
should be on the disk somewhere for you
to have a bugger about with. Probably.
Next issue I'll add some more features,
like animated deaths, an intro and end
effect, a highscore and some bonus
weapons... But 'till then I'll bid you
a fond farewell. Goodbye!
Billy Allan - 1993.