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 >
Text File  |  1987-04-22  |  12KB  |  418 lines

  1.  
  2.        The Missing Link Tutorial
  3.       By Billy Allan of Top Notch
  4.  
  5.     Part One - A Basic Shoot-Em-Up.
  6.  
  7.  
  8.  So, you've got STOS, got The Missing
  9. Link (where's that sound of dripping
  10. water coming from?) and got an idea for
  11. a game. Great. Unfortunately after this
  12. usually comes the more tricky part -
  13. writing the bloody thing!
  14.  Well, over the next few issues I'll be
  15. taking you through, stage by stage, to
  16. write a complete shoot-em-up. I am
  17. assuming that everyone reading this has
  18. written a game or a few programs in STOS
  19. already and generally knows all the
  20. basic stuff (what variables are and the
  21. rest of it). I suppose it's aimed at
  22. the, what "proper" publications call,
  23. intermediate to advanced STOS programmer
  24.  
  25.  In this first section I'll just go
  26. through a listing of a little shoot-em-
  27. up I knocked together which I'll be
  28. using as a base from which the future
  29. articles will be built upon.
  30.  The game, as stands, has 10 aliens with
  31. one bullet each, a vertically scrolling
  32. landscape in the background and a main
  33. player sprite with 4 bullets. It also
  34. has collision detection between sprites,
  35. a lives system, a score counter and some
  36. sound effects.
  37.  
  38.                 - - - -
  39.  
  40. 20 if length(1)=0 then load "gamebob.mbk
  41.   ",1
  42. 30 if length(5)=0 then load "backblk.mbk
  43.   ",5
  44. 40 if length(6)=0 then load "map.mbk",6
  45. 50 if length(10)=0 then reserve as data
  46.    10,10000 : bload "awesome1.mus",10
  47.  
  48.  Lines 20-50 load in the data files
  49. needed by the game. I always use the "if
  50. length(x)=0 then..." to load in data
  51. files. It saves a lot of time as the
  52. file is only loaded once and then is
  53. automatically skipped every time you run
  54. the game after that.  When you save the
  55. source you can just erase all of the
  56. memory banks and when you run it next
  57. time they'll automatically load back in.
  58.  
  59.  
  60. 60 dim BX(9),BY(9),BON(9),BIMG(9),BDR(9)
  61. 70 dim BBX(9),BBY(9),BBON(9),BBIMG(9)
  62. 80 dim BULX(4),BULY(4),BULON(4),BULIMG
  63.   (4)
  64.  
  65.  Set up the arrays for the aliens, alien
  66. bullets and player bullets respectively.
  67.  
  68.  
  69. 180 S1=start(1) : S10=start(10) : S5=
  70.   start(5) : S6=start(6)
  71.  
  72.  Set up pointers to each of the used
  73. memory banks as using Sx is faster than
  74. START(x).
  75.  
  76.  
  77. 200 many bob 0,0,320,192,0,0,0,0,0,1
  78. 210 bob 0,0,320,192,0,1
  79. 220 landscape 0,0,320,192,0,1 : MY=1408
  80.   : SCR=0 : LIV=5
  81.  
  82.  Set the clipping for each command which
  83. is used. Then set up three variables. MY
  84. is the Map Y, SCR is the SCoRe and LIV
  85. is the number of LIVes.
  86.  
  87.  
  88. 230 D=palt(S1) : wait vbl
  89.  
  90.  
  91.  Get the palette. Notice the WAIT VBL -
  92. this is because the PALT command only
  93. changes the palette at the next VBL 
  94. (move.l #palt,$45a.w actually).
  95.  
  96.  
  97. 240 CNT=0 : SCNT=0 : SFX=0
  98. 245 X=160 : Y=160 : IMG=0 : AC=0 : DED=
  99.   false
  100.  
  101.  Set up the variables which *will* be 
  102. re-initialised every time the player
  103. dies. CNT is a counter to give a pause
  104. between the players' bullets, SCNT is a
  105. counter to give pauses between sound
  106. effects, SFX is the music number of the
  107. sound effect to play, X and Y are the
  108. players X and Y co-ordinates, IMG is the
  109. players image number (in the BOB bank),
  110. AC is a flag for whether the player is
  111. accelerating and DED is is a flag for
  112. the player dying.
  113.  
  114.  
  115. 246 for T=0 to 9
  116. 247 BX(T)=rnd(144)*2 : BY(T)=-rnd(100)
  117. 248 BON(T)=1 : BIMG(T)=7 : BDR(T)=rnd(1)
  118.   *2 : if BDR(T)=0 then BDR(T)=-2
  119. 249 BBX(T)=-32 : BBY(T)=-32 : BBON(T)=0
  120.   : BBIMG(T)=12 : next T
  121.  
  122.  This sets up the parameters for the
  123. baddies and their bullets.
  124.  
  125.  
  126. 250 for T=0 to 4
  127. 251 BULX(T)=-32 : BULY(T)=-32 : BULON(T)
  128.   =0 : BULIMG(T)=6
  129. 252 next T
  130.  
  131.  Set up the players bullets.
  132.  
  133.  
  134.      >>>>  Now the main loop  <<<<
  135.  
  136. 280 landscape logic,S5,S6,0,MY,0
  137.  
  138.  Draw the background.
  139.  
  140.  
  141. 285 T=string(SCR) : text logic,0,T,0,24
  142. 286 T=string(LIV) : text logic,0,T,20,24
  143.  
  144.  Display the score and number of lives left.
  145.  
  146.  
  147. 290 dec MY : if MY<0 then MY=1408
  148.  
  149.  Move the map's Y up and wrap it at zero.
  150.  
  151.  
  152. 300 many bob logic,S1,varptr(BIMG(0)),
  153.   varptr(BX(0)),varptr(BY(0)),varptr(BON
  154.   (0)),0,0,9,0
  155. 310 many bob logic,S1,varptr(BBIMG(0)),
  156.   varptr(BBX(0)),varptr(BBY(0)),varptr
  157.   (BBON(0)),0,0,9,0
  158. 320 many bob logic,S1,varptr(BULIMG(0)),
  159.   varptr(BULX(0)),varptr(BULY(0)),varptr
  160.   (BULON(0)),0,0,3,0
  161. 330 bob logic,S1,IMG+AC,X,Y,0
  162.  
  163.  Draw all of the sprites. Notice in line
  164. 330 the IMG+AC. The way the players ship
  165. is stored is: Left/left+engine flames
  166. (EF); Centre/centre+EF; Right/right+EF.
  167. This means that I only need to set the
  168. AC var to 1 to get the correct image for
  169. the accelerated rather than usually
  170. doing something like "if jup then IMG=6"
  171. or whatever. I really ought to have set
  172. up pointer for each of the arrays
  173. (something like VBON=varptr(BON(0)))
  174. where I set up S1, S5 etc., but I
  175. couldn't be bothered.
  176.  
  177.  
  178. 340 for T=0 to 9
  179. 350 if BON(T)=0 then BX(T)=rnd(144)*2 :
  180.   BY(T)=-rnd(50) : BON(T)=1 : BIMG(T)=7
  181.   : goto 400
  182. 360 if BIMG(T)=7 then BX(T)=BX(T)+BDR(T)
  183.   : if BX(T)>286 or BX(T)<2 then BDR(T)=
  184.   -BDR(T)
  185. 370 BY(T)=BY(T)+2 : if BY(T)>200 then BY
  186.   (T)=-rnd(50)
  187. 380 if BBON(T)=0 and BX(T) mod 16=0 then
  188.   inc BIMG(T) : if BIMG(T)>11 then BIMG
  189.   (T)=7 : BBON(T)=1 : BBX(T)=BX(T)+12 :
  190.   BBY(T)=BY(T)+24 : if SCNT=0 then SFX=5
  191.   : SCNT=2
  192. 390 if BBON(T)=1 then BBY(T)=BBY(T)+4 :
  193.   if BBY(T)>200 then BBY(T)=-32 : BBON
  194.   (T)=0
  195. 400 next T
  196.  
  197.  This is the control loop for the
  198. baddies and their bullets. Line 350
  199. checks if the baddie is off (BON=0) and
  200. sets up new parameters for it if it is,
  201. then skips to the end of the loop. Line
  202. 360 checks to see if the baddie is *not*
  203. firing (BIMG=7). If it not firing then
  204. it is moved accross the screen. Line 370
  205. moves the baddie down the screen by two
  206. pixels and wraps it at 200. Line 380
  207. checks if the baddies bullet is turned
  208. off (BBON=0) and it is on a 16-pixel
  209. boundary (BX mod 16=0). If so it anim-
  210. ates the baddie sprite until its image
  211. reaches 11, then it fires a bullet. Line
  212. 390 checks if the bullet is on (BBON=1)
  213. then it moves the bullet down the screen
  214. and turns it off if it reaches the
  215. bottom of the screen.
  216.  
  217.  
  218. 410 for T=0 to 3 : if BULON(T)=0 then
  219.   goto 450
  220. 420 BULY(T)=BULY(T)-6 : if BULY(T)<0
  221.   then BULON(T)=0
  222. 430 R=many overlap(BULX(T),BULY(T),
  223.   varptr(BX(0)),varptr(BY(0)),32,8,32,16
  224.   ,varptr(BON(0)),varptr(BBON(0)),0,0,9)
  225. 440 if R>0 then BULON(T)=0 : if SCNT=0
  226.   or SFX=5 then SFX=8 : SCNT=5 : SCR=SCR
  227.   +R*10
  228. 450 next T
  229.  
  230.  This is the loop for the players
  231. bullets. Line 410 checks if the bullet
  232. is off (BULON=0) and skips the loop if
  233. it is. Line 420 moves the bullet up the
  234. screen and turns it off it it hits the
  235. top of the screen. Line 430 does the
  236. collision detection between the players
  237. bullets and the baddie ships. Line 440
  238. turns off the bullet if it collided with
  239. anything and sets the sound effect vari-
  240. able to 8 if the SCNT vcounter is zero
  241. or the current sound effect is 5 (ie,
  242. baddie firing noise). It then adds some
  243. points onto the score.
  244.  
  245.  
  246. 451 R=many overlap(X,Y,varptr(BBX(0)),
  247.   varptr(BBY(0)),32,28,4,4,varptr(BBON
  248.   (0)),varptr(BBON(0)),0,0,9)
  249. 452 if R>0 then DED=true : dec LIV
  250. 453 R=many overlap(X,Y,varptr(BX(0)),
  251.   varptr(BY(0)),32,28,32,16,varptr(BON
  252.   (0)),varptr(BBON(0)),0,0,9)
  253. 454 if R>0 then DED=true : dec LIV
  254.  
  255.  Line 451-454 do the collisions between
  256. the baddies, baddie bullets and the
  257. player. If the player hits any of them
  258. then the DED flag is set and the lives
  259. are decreased.
  260.  
  261.  
  262. 460 if not(jleft) and not(jright) then
  263.   IMG=2
  264. 470 if jleft and X>0 then X=X-4 : IMG=0
  265. 480 if jright and X<288 then X=X+4 : IMG
  266.   =4
  267. 490 OY=Y : if jup and Y>100 then Y=Y-4
  268. 500 if jdown and Y<160 then Y=Y+4
  269. 510 if Y<>OY then AC=1 else AC=0
  270. 520 if fire+CNT=-1 then gosub 620
  271.  
  272.  The player controls. Line 460 checks to
  273. see if neither left or right was pressed
  274. and sets the players image to the
  275. "normal" position if so (2). Line 470-
  276. 480 moves left or right and sets the
  277. image number. Line 490-500 check if the
  278. ship is moving up or down. Notice that
  279. I've stored the old Y on OY. This is to
  280. be checked in line 510 against the
  281. current Y to see if any vertical move-
  282. ment occured, and if so the acceleration
  283. flag (AC) is set. Line 520 checks if
  284. fire was pressed and the CNT counter is
  285. 0 (therefore fire+CNT would equal -1, ie
  286. fire=TRUE and CNT=0) and jumps to the
  287. FIRE subroutine if so.
  288.  
  289.  
  290. 530 if CNT>0 then dec CNT
  291. 540 if SFX>0 then musplay S10,SFX,6 :
  292.   SFX=0
  293. 550 if SCNT>0 then dec SCNT
  294.  
  295.  Lines 530+550 decrease the two game
  296. counters. Line 540 plays the sound
  297. effect if the sound effect variable
  298. (SFX) is set.
  299.  
  300.  
  301. 560 screen swap : wait vbl
  302.  
  303.  Do the screen swap.
  304.  
  305.  
  306. 570 if inkey$<>" " and not(DED) then
  307.   goto 280
  308.  
  309.  Loop back to the start if space wasn't
  310. pressed and the DED flag isn't set.
  311.  
  312.  
  313. 575 if DED then fade 3 : for T=1 to 28 :
  314.   wait vbl : next T : wipe logic : wipe
  315.   physic : if LIV>-1 then goto 230
  316. 580 musplay 0,0,0 : wait vbl : default :
  317.   end
  318.  
  319.  Line 575 checks if the player is DEaD,
  320. and fades to black if so. If it then
  321. finds that the lives are still valid
  322. (>=0) then it loops back to the initial-
  323. isation section. Line 580 turns off the
  324. music and exits.
  325.  
  326.       >>>>  The FIRE routine  <<<<
  327.  
  328. 620 Q=0 : while BULON(Q)=1 and Q<4 : inc
  329.   Q : wend
  330. 630 if Q=4 then return
  331. 640 if SCNT=0 and SFX<>5 then SFX=4 :
  332.   SCNT=3
  333. 650 BULX(Q)=X : BULY(Q)=Y : BULON(Q)=1 :
  334.   CNT=5 : return
  335.  
  336.  This is my usual multi-fire routine.
  337. Line 620 goes through the list of bullet
  338. status flags until it either finds that
  339. one is clear or it reaches the end of
  340. the array. Line 630 returns back to the
  341. main loop if the end of the array was
  342. reached. Line 640 sets the fire sound
  343. effect if the counter is zero and the
  344. sound effect doesn't equal 5 (baddie
  345. fire). Line 650 sets up the bullets par-
  346. ameters and returns. Note that CNT is
  347. set to 5. This means that the player
  348. cannot fire until the main loop has been
  349. executed a further 5 times.
  350.  
  351.                 - - - -
  352.  
  353.  Well, I should think that's about as
  354. clear as the script for Twin Peaks now,
  355. so I'll bore you with some of the
  356. general features of the program.
  357.  The first thing to notice is the 
  358. general structure of the main loop. The
  359. graphics are drawn and *then* they are
  360. moved. I find that this is usually the
  361. easiest way of doing things, but I'm
  362. sure there are just as many who do
  363. things the opposite way (and probably
  364. some who do a mixture of both... The
  365. catflaps of the programming world...).
  366.  Next, you may be wondering why the
  367. baddies stop moving horizontally when
  368. they are firing, and indeed, why they
  369. only fire when they hit a sixteen bound-
  370. ary. This is a memory saving technique,
  371. which although has fairly limited uses,
  372. can be very useful when things get
  373. tight. In the MAKE program I have only
  374. made up one image for each frame of
  375. animation of the baddie ship firing,
  376. where as the ship normally has 4 images.
  377. This means that I have saved 3 * the-
  378. number-of-frames images. The drawback
  379. is, of course, that the sprite can only
  380. be displayed on a 16 pixel boundary.
  381. It's always worth thinking on ways to
  382. save memory by cutting out unneeded
  383. images, especially if you're tight on
  384. memory or disk space. (There is another
  385. side effect in this particular case. As
  386. BOBs on a sixeteen boundary are drawn
  387. more quickly (16 pixels lees are drawn
  388. on the right side of the image) then
  389. this offsets the decrease in speed
  390. caused by the animating sprite becoming
  391. bigger in the Y axis.)
  392.  The next thing to notice is the use of
  393. the two counters - CNT and SCNT. After
  394. writing games for some time I've found
  395. that these are the most convenient way
  396. of adding a delay to the firing and
  397. sound effects. SCNT is more involved as
  398. new sound effects can only be started if
  399. it is zero and if a sound effect with a
  400. higher priority has not already been
  401. started. The counter is also set to dif-
  402. ferent lengths for the different sound
  403. effects.
  404.  Other than that, I don't think there's
  405. much to say about it really. The source
  406. should be on the disk somewhere for you
  407. to have a bugger about with. Probably.
  408.  
  409.  Next issue I'll add some more features,
  410. like animated deaths, an intro and end
  411. effect, a highscore and some bonus
  412. weapons...  But 'till then I'll bid you
  413. a fond farewell. Goodbye!
  414.  
  415.  
  416.           Billy Allan - 1993.
  417.  
  418.