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 >
Text File  |  1990-05-15  |  10KB  |  224 lines

  1.                               Array the sprites!
  2.  
  3.                     Phil Lawson continues his STOS series
  4.                      started in Atari ST User by showing
  5.                       how to obtain much greater control
  6.                       over your sprites by using arrays
  7.  
  8. WE finished last time (in the June issue of Atari ST User) with a small program
  9. called CHASE.BAS which demonstrated how several sprites can be made to head
  10. towards another and I promised I'd tell you exactly how it works in this
  11. issue.
  12.     If you missed last month's issue then load CHASE.BAS into STOS and run it -
  13. you'll see that four sprites follow a square controlled by the joystick. The
  14. interesting part of the program lies between lines 1040 and 2020:
  15.  
  16.   1040 xd=0 : yd=0 : j=JOY : IF j=1 THEN yd=-2 ELSE IF j=2 THEN yd=2 ELSE
  17. IF j=4 THEN xd=-2 ELSE IF j=8 THEN xd=2
  18.   1050 IF x+xd<300 AND x+xd>10 AND y+yd<190 AND y+yd>10 THEN x=x+xd : y=y
  19. +yd :SPRITE 6,x,y
  20.   1060 GOSUB 2000
  21.   1070 WEND
  22.   2000 sp=RND(4)+1:xp(sp)=xp(sp)+(2*SGN(x-xp(sp))):yp(sp)=yp(sp)+(2*SGN(y
  23. -yp(sp)))
  24.   2010 SPRITE sp,xp(sp),yp(sp)
  25.   2020 RETURN
  26.  
  27.     Line 1040 checks the position of the joystick and sets the two variables xd
  28. and yd accordingly. For instance, if the stick was moved to the left, the value
  29. of yd would be -2, and moving it down gives an xd value of 2. The actual number
  30. indicates how many pixels the sprite will be moved and I suggest you play
  31. around with this line to see how different values will affect the program.
  32.     To move the sprite we simply add xd and yd to the X and Y coordinates of
  33. the sprite, after first checking it won't be moved off the screen. Line 1050
  34. does this for us and you can see that negative values will cause the sprite to
  35. either move up or left, with positive numbers resulting in down or right
  36. movement.
  37.     Moving all the other sprites towards the main one is achieved with line
  38. 2000. This chooses one of the four at random and calculates its position on the
  39. screen relative to the user-controlled sprite, and moves it one pixel in this
  40. direction. The function SGN returns one of three values - 1, 0 or +1, depending
  41. on the sign of the result within the brackets.
  42.     The reason I moved a randomly choosen sprite is that with four on the go at
  43. the same time and often overlapping each other, the program tended to slow
  44. down. Using this method, games with many sprites displayed at the same time can
  45. be greatly speeded up, without affecting the overall gameplay.
  46.     Try experimenting with line 2000 to see different effects. For example,
  47. changing it to the following will make all the sprites run away from the main
  48. one.
  49.  
  50.   2000 sp=RND(4)+1 : xp(sp)=xp(sp)+(2*SGN(xp(sp)-x)) : yp(sp)=yp(sp)+(2*SGN
  51. (yp(sp)-y))
  52.  
  53.     You should all be familiar with the following routine by now, which changes
  54. the palette to that defined within the sprite bank. Notice that all the
  55. programs this month will need this routine:
  56.  
  57.   26000 REM get sprite colours
  58.   26010 x=HUNT(START(1) TO START(1)+LENGTH(1),"PALT")+426020 FOR l=0 TO 15
  59.  : COLOUR l,DEEK(x): INC x : INC x : NEXT
  60.   26030 RETURN
  61.  
  62.     We have already discovered that simple sprite paths can be obtained with
  63. the MOVE command, but to do anything other than straight lines would require so
  64. many parameters that this method becomes impractical. Another way of storing
  65. the sprite path is to define an array, into which we store all the points the
  66. sprite is to pass through, and position it at each one in turn. Load and run
  67. STOS1.BAS. Here is the core of the program:
  68.  
  69.   25000 REM Program I
  70.   25010 MODE 0 : KEY OFF
  71.   25020 CURS OFF : HIDE
  72.   25030 GOSUB 26000
  73.   25040 DIM xp(360),yp(360) : ox=80 : oy=100 : r=60
  74.   25050 FOR a=1 TO 360 : angle#=RAD(a)
  75.   25060 xp(a)=ox+(SIN(angle#)*r) : yp(a)=oy-(COS(angle#)*r)
  76.   25070 NEXT
  77.   25080 FOR a=1 TO 360
  78.   25090 SPRITE 1,xp(a),yp(a),1
  79.   25100 UPDATE : NEXT a
  80.   25110 GOTO 25080
  81.  
  82.     This program stores the X and Y coordinates of a circle and displays the
  83. sprite at each one, giving the appearance that it is moving in a circular path.
  84. Lines 25050 and 25060 are simple mathematical rules for obtaining the
  85. coordinates of each point on a circle, given the position of the centre, (ox
  86. and oy), and the radius, (r).
  87.     You needn't worry about how it works, but adding line 25065 will show each
  88. point as it's calculated.
  89.  
  90.   25065 PLOT xp(a),yp(a)
  91.  
  92.     Notice that line 25050 sets the variable angle# to be the RADIAN of a,
  93. because the functions SIN and COS expect the angle to be given in radians. The
  94. # is used to inform STOS that this variable is a floating point number, so
  95. everything after the decimal point will not be discarded.
  96.     To see what I mean, enter the following commands:
  97.  
  98.   value=123.456
  99.   value#=123.456
  100.   PRINT value
  101.   PRINT value#
  102.  
  103.     Lines 25080 to 25110 just position the sprite at each coordinate in turn.
  104. The formula we used can produce patterns other than circles and to see one of
  105. these try adding the following line line 25095:
  106.  
  107.   25095 SPRITE 2,xp(a)+a/2,yp(a),1
  108.  
  109. Wave upon wave
  110. ---------------
  111. You may have noticed that apart from great big monsters at the end of levels,
  112. not many games use aliens travelling in a circular path. In fact, most of them
  113. tend to appear at one side of the screen and move towards the other, either in
  114. a straight line or using an up and down wave effect.
  115.     This can be easily achieved in STOS using the array method as shown in
  116. STOS2.BAS:
  117.  
  118.   25000 REM Program II
  119.   25010 MODE 0 : KEY OFF
  120.   25020 CURS OFF : HIDE
  121.   25030 GOSUB 26000
  122.   25040 DIM xp(640),yp(640)
  123.   25050 FOR a=1 TO 640 : angle#=RAD(a)
  124.   25060 xp(a)=a/2 : yp(a)=SIN(angle#)*90+90
  125.   25070 NEXT
  126.   25080 FOR a=1 TO 640
  127.   25090 SPRITE 1,xp(a),yp(a),1
  128.   25100 UPDATE : NEXT a
  129.   25110 GOTO 25080
  130.  
  131.     Here we see the sprite moving across the screen in what is refered to as a
  132. sine-wave pattern, where all the points have been defined with lines 25050 to
  133. 25070. The mathematically minded among you will probably know that the opposite
  134. of SIN is COS, which means that a few changes can give us two sprites both
  135. moving left to right, but appearing to be the mirror image of each other:
  136.  
  137.   25040 DIM xp(640),yp(640,2)
  138.   25060 xp(a)=a/2:yp(a,1)=SIN(angle#)*90+90
  139.   25065 yp(a,2)=COS(angle#)*(-90)+90
  140.   25090 SPRITE 1,xp(a),yp(a,1),1
  141.   25095 SPRITE 2,xp(a),yp(a,2),1
  142.  
  143.     So far we have only concentrated on sprites following their own pre-defined
  144. path, without appearing as part of the same attack wave. Our final program this
  145. month shows three sprites, all following the same path, but slightly behind
  146. each other:
  147.  
  148.   25000 REM Program 3
  149.   25010 MODE 0 : KEY OFF
  150.   25020 CURS OFF : HIDE
  151.   25030 GOSUB 26000
  152.   25040 DIM xp(470),yp(470),pn(3,470)
  153.   25050 FOR a=1 TO 100
  154.   25060 xp(a)=250 : yp(a)=a-20
  155.   25070 NEXT a
  156.   25080 FOR a=101 TO 300
  157.   25090 xp(a)=350-a : yp(a)=80
  158.   25100 NEXT a
  159.   25110 FOR a=301 TO 470
  160.   25120 xp(a)=50 : yp(a)=380-a
  161.   25130 NEXT a
  162.   25140 FOR a=1 TO 470
  163.   25150 pn(1,a)=a : pn(2,a)=a-30 : pn(3,a)=a-60
  164.   25160 NEXT a
  165.   25170 FOR a=1 TO 470
  166.   25180 SPRITE 1,xp(pn(1,a)),yp(pn(1,a)),1
  167.   25190 IF pn(2,a)>0 THEN SPRITE 2,xp(pn(2,a)),yp(pn(2,a)),1
  168.   25200 IF pn(3,a)>0 THEN SPRITE 3,xp(pnp(3,a)),yp(pn(3,a)),1
  169.   25210 UPDATE : NEXT a : GOTO 25170
  170.  
  171.     Up to line 25130 the code is fairly easy to understand, as this part only
  172. defines the X and Y positions for the arrays xp and yp. However, things start
  173. to become more complex from this point onwards.
  174.     The array pn is used to store the position number of each sprite and lines
  175. 25140 to 25160 set the second sprite 30 steps behind the first, with the third
  176. sprite being 60 steps behind.
  177.     Looking at lines 25190 shows that the second sprite won't be activated
  178. until the value of a is 30, (pn(2,30)=1), at which point the first sprite will
  179. have been moved 30 times. The third sprite waits until the value of a becomes
  180. 60, (pn(3,60)=1).
  181.     So, after 30 steps the first sprite has been moved 30 times and the program
  182. now starts to move the second one as well. The program continues until the
  183. first sprite has been moved a total of 60 steps, when the third and last sprite
  184. starts to be moved along with the other two.
  185.     The three sprites will now continue moving down the screen and as each one
  186. reaches the centre it will start to move to the left. When each sprite reaches
  187. the X coordinate 50, it will move upwards and finally disappear off the top of
  188. the screen.
  189.     You may think that some of the routines shown here are rather slow, but
  190. don't worry as they only show the general effects possible. To speed them up
  191. try adding the command:
  192.  
  193. STEP 2
  194.  
  195. or
  196.  
  197. STEP 4
  198.  
  199. after the FOR instructions. Once a sprite has been defined, you can speed it up
  200. by ommiting the pattern number from the end. For example:
  201.  
  202. SPRITE number,x,y
  203.  
  204.     The only problem with storing the data in arrays is that you have to put it
  205. there in the first place. For simple paths this can often be done with a
  206. mathematical formula, but more complicated ones require some form of Sprite
  207. Path Definer.
  208.     Luckily I'm working on just such a program at the moment and it'll appear
  209. on the Cover Disk when it is finished. The features it will include are going
  210. to make this program a must for every STOS owner, so take out a subscription as
  211. soon as possible!
  212. * That's all for now. If you have any problems or hints and tips then write and
  213. let me know. See you on next month's Cover Disk.
  214.  
  215.  
  216. Hints and Tips
  217. ---------------
  218. This month's tip comes from Barry Redmond of Bristol and concerns the screen
  219. compactor accessory. If only a small part of the screen is used, try packing
  220. the whole screen as well packing just that area.
  221.     Since packing the whole screen uses eight different compaction routines,
  222. you'll quite often find that resulting memory bank is shorter than if you'd
  223. only relied on the Pack Part of Screen option.
  224.