home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
No Fragments Archive 10: Diskmags
/
nf_archive_10.iso
/
MAGS
/
ST_USER
/
1990
/
USERJL90.MSA
/
TEXT_STOS.DOC
< prev
next >
Wrap
Text File
|
1990-05-15
|
10KB
|
224 lines
Array the sprites!
Phil Lawson continues his STOS series
started in Atari ST User by showing
how to obtain much greater control
over your sprites by using arrays
WE finished last time (in the June issue of Atari ST User) with a small program
called CHASE.BAS which demonstrated how several sprites can be made to head
towards another and I promised I'd tell you exactly how it works in this
issue.
If you missed last month's issue then load CHASE.BAS into STOS and run it -
you'll see that four sprites follow a square controlled by the joystick. The
interesting part of the program lies between lines 1040 and 2020:
1040 xd=0 : yd=0 : j=JOY : IF j=1 THEN yd=-2 ELSE IF j=2 THEN yd=2 ELSE
IF j=4 THEN xd=-2 ELSE IF j=8 THEN xd=2
1050 IF x+xd<300 AND x+xd>10 AND y+yd<190 AND y+yd>10 THEN x=x+xd : y=y
+yd :SPRITE 6,x,y
1060 GOSUB 2000
1070 WEND
2000 sp=RND(4)+1:xp(sp)=xp(sp)+(2*SGN(x-xp(sp))):yp(sp)=yp(sp)+(2*SGN(y
-yp(sp)))
2010 SPRITE sp,xp(sp),yp(sp)
2020 RETURN
Line 1040 checks the position of the joystick and sets the two variables xd
and yd accordingly. For instance, if the stick was moved to the left, the value
of yd would be -2, and moving it down gives an xd value of 2. The actual number
indicates how many pixels the sprite will be moved and I suggest you play
around with this line to see how different values will affect the program.
To move the sprite we simply add xd and yd to the X and Y coordinates of
the sprite, after first checking it won't be moved off the screen. Line 1050
does this for us and you can see that negative values will cause the sprite to
either move up or left, with positive numbers resulting in down or right
movement.
Moving all the other sprites towards the main one is achieved with line
2000. This chooses one of the four at random and calculates its position on the
screen relative to the user-controlled sprite, and moves it one pixel in this
direction. The function SGN returns one of three values - 1, 0 or +1, depending
on the sign of the result within the brackets.
The reason I moved a randomly choosen sprite is that with four on the go at
the same time and often overlapping each other, the program tended to slow
down. Using this method, games with many sprites displayed at the same time can
be greatly speeded up, without affecting the overall gameplay.
Try experimenting with line 2000 to see different effects. For example,
changing it to the following will make all the sprites run away from the main
one.
2000 sp=RND(4)+1 : xp(sp)=xp(sp)+(2*SGN(xp(sp)-x)) : yp(sp)=yp(sp)+(2*SGN
(yp(sp)-y))
You should all be familiar with the following routine by now, which changes
the palette to that defined within the sprite bank. Notice that all the
programs this month will need this routine:
26000 REM get sprite colours
26010 x=HUNT(START(1) TO START(1)+LENGTH(1),"PALT")+426020 FOR l=0 TO 15
: COLOUR l,DEEK(x): INC x : INC x : NEXT
26030 RETURN
We have already discovered that simple sprite paths can be obtained with
the MOVE command, but to do anything other than straight lines would require so
many parameters that this method becomes impractical. Another way of storing
the sprite path is to define an array, into which we store all the points the
sprite is to pass through, and position it at each one in turn. Load and run
STOS1.BAS. Here is the core of the program:
25000 REM Program I
25010 MODE 0 : KEY OFF
25020 CURS OFF : HIDE
25030 GOSUB 26000
25040 DIM xp(360),yp(360) : ox=80 : oy=100 : r=60
25050 FOR a=1 TO 360 : angle#=RAD(a)
25060 xp(a)=ox+(SIN(angle#)*r) : yp(a)=oy-(COS(angle#)*r)
25070 NEXT
25080 FOR a=1 TO 360
25090 SPRITE 1,xp(a),yp(a),1
25100 UPDATE : NEXT a
25110 GOTO 25080
This program stores the X and Y coordinates of a circle and displays the
sprite at each one, giving the appearance that it is moving in a circular path.
Lines 25050 and 25060 are simple mathematical rules for obtaining the
coordinates of each point on a circle, given the position of the centre, (ox
and oy), and the radius, (r).
You needn't worry about how it works, but adding line 25065 will show each
point as it's calculated.
25065 PLOT xp(a),yp(a)
Notice that line 25050 sets the variable angle# to be the RADIAN of a,
because the functions SIN and COS expect the angle to be given in radians. The
# is used to inform STOS that this variable is a floating point number, so
everything after the decimal point will not be discarded.
To see what I mean, enter the following commands:
value=123.456
value#=123.456
PRINT value
PRINT value#
Lines 25080 to 25110 just position the sprite at each coordinate in turn.
The formula we used can produce patterns other than circles and to see one of
these try adding the following line line 25095:
25095 SPRITE 2,xp(a)+a/2,yp(a),1
Wave upon wave
---------------
You may have noticed that apart from great big monsters at the end of levels,
not many games use aliens travelling in a circular path. In fact, most of them
tend to appear at one side of the screen and move towards the other, either in
a straight line or using an up and down wave effect.
This can be easily achieved in STOS using the array method as shown in
STOS2.BAS:
25000 REM Program II
25010 MODE 0 : KEY OFF
25020 CURS OFF : HIDE
25030 GOSUB 26000
25040 DIM xp(640),yp(640)
25050 FOR a=1 TO 640 : angle#=RAD(a)
25060 xp(a)=a/2 : yp(a)=SIN(angle#)*90+90
25070 NEXT
25080 FOR a=1 TO 640
25090 SPRITE 1,xp(a),yp(a),1
25100 UPDATE : NEXT a
25110 GOTO 25080
Here we see the sprite moving across the screen in what is refered to as a
sine-wave pattern, where all the points have been defined with lines 25050 to
25070. The mathematically minded among you will probably know that the opposite
of SIN is COS, which means that a few changes can give us two sprites both
moving left to right, but appearing to be the mirror image of each other:
25040 DIM xp(640),yp(640,2)
25060 xp(a)=a/2:yp(a,1)=SIN(angle#)*90+90
25065 yp(a,2)=COS(angle#)*(-90)+90
25090 SPRITE 1,xp(a),yp(a,1),1
25095 SPRITE 2,xp(a),yp(a,2),1
So far we have only concentrated on sprites following their own pre-defined
path, without appearing as part of the same attack wave. Our final program this
month shows three sprites, all following the same path, but slightly behind
each other:
25000 REM Program 3
25010 MODE 0 : KEY OFF
25020 CURS OFF : HIDE
25030 GOSUB 26000
25040 DIM xp(470),yp(470),pn(3,470)
25050 FOR a=1 TO 100
25060 xp(a)=250 : yp(a)=a-20
25070 NEXT a
25080 FOR a=101 TO 300
25090 xp(a)=350-a : yp(a)=80
25100 NEXT a
25110 FOR a=301 TO 470
25120 xp(a)=50 : yp(a)=380-a
25130 NEXT a
25140 FOR a=1 TO 470
25150 pn(1,a)=a : pn(2,a)=a-30 : pn(3,a)=a-60
25160 NEXT a
25170 FOR a=1 TO 470
25180 SPRITE 1,xp(pn(1,a)),yp(pn(1,a)),1
25190 IF pn(2,a)>0 THEN SPRITE 2,xp(pn(2,a)),yp(pn(2,a)),1
25200 IF pn(3,a)>0 THEN SPRITE 3,xp(pnp(3,a)),yp(pn(3,a)),1
25210 UPDATE : NEXT a : GOTO 25170
Up to line 25130 the code is fairly easy to understand, as this part only
defines the X and Y positions for the arrays xp and yp. However, things start
to become more complex from this point onwards.
The array pn is used to store the position number of each sprite and lines
25140 to 25160 set the second sprite 30 steps behind the first, with the third
sprite being 60 steps behind.
Looking at lines 25190 shows that the second sprite won't be activated
until the value of a is 30, (pn(2,30)=1), at which point the first sprite will
have been moved 30 times. The third sprite waits until the value of a becomes
60, (pn(3,60)=1).
So, after 30 steps the first sprite has been moved 30 times and the program
now starts to move the second one as well. The program continues until the
first sprite has been moved a total of 60 steps, when the third and last sprite
starts to be moved along with the other two.
The three sprites will now continue moving down the screen and as each one
reaches the centre it will start to move to the left. When each sprite reaches
the X coordinate 50, it will move upwards and finally disappear off the top of
the screen.
You may think that some of the routines shown here are rather slow, but
don't worry as they only show the general effects possible. To speed them up
try adding the command:
STEP 2
or
STEP 4
after the FOR instructions. Once a sprite has been defined, you can speed it up
by ommiting the pattern number from the end. For example:
SPRITE number,x,y
The only problem with storing the data in arrays is that you have to put it
there in the first place. For simple paths this can often be done with a
mathematical formula, but more complicated ones require some form of Sprite
Path Definer.
Luckily I'm working on just such a program at the moment and it'll appear
on the Cover Disk when it is finished. The features it will include are going
to make this program a must for every STOS owner, so take out a subscription as
soon as possible!
* That's all for now. If you have any problems or hints and tips then write and
let me know. See you on next month's Cover Disk.
Hints and Tips
---------------
This month's tip comes from Barry Redmond of Bristol and concerns the screen
compactor accessory. If only a small part of the screen is used, try packing
the whole screen as well packing just that area.
Since packing the whole screen uses eight different compaction routines,
you'll quite often find that resulting memory bank is shorter than if you'd
only relied on the Pack Part of Screen option.