home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
No Fragments Archive 10: Diskmags
/
nf_archive_10.iso
/
MAGS
/
ST_USER
/
1990
/
USERSP90.MSA
/
TEXT_STOS.DOC
< prev
next >
Wrap
Text File
|
1990-07-25
|
9KB
|
206 lines
One over the eight
Phil Lawson's STOS series continues to manipulate the
humble sprite and gets it bouncing in eight directions
Last month we discovered how to bounce a sprite around a simple maze in four
directions, namely up, down, left and right. This month we'll expand these
concepts to cover the other four diagonal directions. If you'd rather examine
my code to work it out yourself, you'll find the program and Degas picture on
this cover disk.
You should remember Table I from last month, which was used to calculate
the new direction of a ball after it had struck an obstacle. If you don't have
that issue, order a back copy now as we'll be using the points discussed quite
often in future issues.
original direction
left(1) up(2) right(3) down(4)
1 2 0 0 3
obtained 2 4 3 0 0
value 3 0 1 4 0
4 0 0 2 1
Table I: Cross referencing the obtained value with the original direction.
These values were stored in a 4X4 array, which could be quickly accessed
to set the new direction. If you recall, we defined four points around the
centre of the sprite and tested the background colour under these to determine
what type of obstacle was hit. This was fine because there were only four
possible obstables and four directions. Now however, there are eight of each
which means a slight re-think in required, not to mention a bigger array.
Since only one of the four points could have been set at any one time, we
just checked which one it was, ( one to four ) and used that as one of the
array parameters. Unfortunately with eight directions there will be either two
or three points set, so how do we combine these to produce one number which can
be passed to the array?
Consider the binary number 0000. Each bit represents a different power of
2, namely 8,4,2 and 1. If a bit is set we simply add its corresponding number
to a total to find what the original binaray number represent in our normal
denary system. For example, if the number was 1011, we'd add togeather 8,2 and
1 to obtain a total of eleven.
If we made each of the four points correspond to one of the bits, we could
check whether that point was set and if so set the appropiate bit, as shown in
lines 2030 to 2060 of this months program:
10 REM Demonstration of 8-way bouncing
11 REM by Phil Lawson for Atari ST User (c) 1990
12 REM *****************************************
20 MODE 0 : KEY OFF : HIDE : CURS OFF
30 UNPACK 5,PHYSIC : WAIT VBL : UNPACK 5,BACK : WAIT VBL
40 GOSUB 500
50 GOSUB 1000
60 STOP
500 REM Initialisation
501 REM **************
510 DIM b(14,8),dx(8),dy(8),sx(6),sy(6),d(6)
520 RESTORE 600 : FOR a=1 TO 8 : READ dx(a),dy(a) : NEXT a
540 RESTORE 700 : FOR a=1 TO 14 : FOR c=1 TO 8 : READ b(a,c) : NEXT c :
NEXT a
550 RESTORE 800 : FOR a=1 TO 6 : READ sx(a),sy(a) : NEXT a
560 RESTORE 820 : FOR a=1 TO 6 : READ d(a) : NEXT a
599 RETURN
600 DATA-1,0,-1,-1,0,-1,1,-1,1,0,1,1,0,1,-1,1
700 DATA 0,0,0,0,0,0,0,0
705 DATA 0,0,0,0,0,0,0,0
710 DATA 5,4,0,0,0,0,0,6
715 DATA 0,0,0,0,0,0,0,0
720 DATA 0,0,0,0,0,0,0,0
725 DATA 0,8,7,6,0,0,0,0
730 DATA 7,6,5,0,0,0,0,0
735 DATA 0,0,0,0,0,0,0,0
740 DATA 0,0,0,0,0,4,3,2
745 DATA 0,0,0,0,0,0,0,0
750 DATA 3,0,0,0,0,0,5,4
755 DATA 0,0,0,2,1,8,0,0
760 DATA 0,0,0,0,3,2,1,0
765 DATA 0,0,1,8,7,0,0,0
790 REM The sprite starting positions
791 REM *****************************
800 DATA 50,32,40,127,64,127
810 DATA 180,34,178,125,222,174
818 REM The initial directions of each sprite
819 REM *************************************
820 DATA 5,2,8,5,7,1
1000 REM Position the balls and start bouncing them
1001 REM ******************************************
1010 FOR a=1 TO 6 : SPRITE a,sx(a),sy(a),1 : NEXT a
1020 WHILE INKEY$=""
1030 FOR a=1 TO 6
1040 sx(a)=sx(a)+dx(d(a)) : sy(a)=sy(a)+dy(d(a))
1050 SPRITE a,sx(a),sy(a),1 : UPDATE
1060 IF DETECT(a)=1 THEN GOSUB 2000
1070 NEXT a
1080 WEND
1090 RETURN
2000 REM Change direction
2001 REM ****************
2020 num=0 : LOGIC=BACK
2030 IF POINT(sx(a)-1,sy(a)+1)=1 THEN num=1
2040 IF POINT(sx(a)-1,sy(a)-1)=1 THEN num=num+2
2050 IF POINT(sx(a)+1,sy(a)-1)=1 THEN num=num+4
2060 IF POINT(sx(a)+1,sy(a)+1)=1 THEN num=num+8
2070 LOGIC=PHYSIC : d(a)=b(num,d(a))
2080 RETURN
Since any two or three of the four points, and therefore the four bits,
could be set it's a good idea to define a table showing all the possibilities
and resulting denary numbers. See Table II:
Which points/bits Corresponding binary Corresponding denary
are set? number number
p1,p2 0011 3
p2,p3 0110 6
p3,p4 1100 12
p4,p1 1001 9
p1,p2,p3 0111 7
p2,p3,p4 1110 14
p3,p4,p1 1101 13
p4,p1,p2 1011 11
Table II: The possible points/bits along with their binary and denary numbers.
The number we obtain from the four points tells us what type of obstacle
has been hit, so all we now need is the original direction the ball was
travelling in and its new direction can be read from an array.
Since there are eight possible directions, I've numbered them from one to
eight .These are show in Figure I and reproduced in Table II.
STOSPIC.PC1:<<SCREENSHOT>>
From these we can set up another table which tells us the new direction.
You'll find this data starting at line 710 in the main program:
Obstacle type Original direction The eight directions
1 2 3 4 5 6 7 8
3 5 4 0 0 0 0 0 6 1 = Left
6 0 8 7 6 0 0 0 0 2 = Left/Up
7 7 6 5 0 0 0 0 0 3 = Up
9 0 0 0 0 0 4 3 2 4 = Right/Up
11 3 0 0 0 0 0 5 4 5 = Right
12 0 0 0 2 1 8 0 0 6 = Right/Down
13 0 0 0 0 3 2 1 0 7 = Down
14 0 0 1 8 7 0 0 0 8 = Left/Down
Table III: Calculating the new direction from the object type and original
direction.
For example, if the original direction was Down and the obstacle type was
13, the new direction can easily be read as 1, or Up. The code which controls
this part of the program is the subroutine at line 2000. Notice that I've had
to use the LOGIC instruction to set the screen on which the POINT command
actually works.
Running the demonstration program shows six sprites, each bouncing in
slightly different ways. I don't normally give complete breakdowns of my
programs, as this prevents you from working things out yourselves and therefore
stops you thinking like a programmer. However, the six arrays used would
probably cause great headaches if some explanation was not given.
B(14,8) Stores the data from Table III.
SX(6) The X-coordinate for each sprite.
SY(6) The Y-coordinate for each sprite.
D(6) The direction of each sprite.
DX(8) What to add to the X coordinate of each sprite.
DY(8) What to add to the Y coordinate of each sprite.
Looking at the main routine of the program, lines 1020 to 1080, shows that
the X and Y coordinates or each sprite is altered by the value of
dx(d(sprite)). Line 600 holds the data for both the DX and DY arrays, which can
be either 1, -1 or 0. This means that the X and Y coordinates will have 1, -1
or zero added to them, depending on the sprite's direction, so giving the
effect of movement.
For example, if the sprite's coordinates were 150 and 90 and it was
travelling down (7), it's new position would be calculated as follows:
X=X+(DX(D(sprite_number)) : Y=Y+(DY(D(sprite_number))
or
X=X+(DX(7) : Y=Y+DY(7)
or
X=X+0 : Y=Y+1
To speed the sprite up a little, try changing line 600 to:
600 DATA -2,0,-2,-2,0,-2,2,-2,2,0,2,2,0,2,-2,2
This cannot normally be done unless the distance between each of the
obstacles is an exact multiple of 2, but luckily the screen I designed had just
that property. To see what would happen if the distances were not correct,
change line 600 to:
600 DATA -4,0,-4,-4,0,-4,4,-4,4,0,4,4,0,4,-4,4
That's all for now. See you on next month's cover disk.