home *** CD-ROM | disk | FTP | other *** search
/ Otherware / Otherware_1_SB_Development.iso / amiga / misc / amoner05.dms / amoner05.adf / Editor / Tutorial.txt < prev   
Encoding:
Text File  |  1992-02-23  |  15.7 KB  |  423 lines

  1. ------------------------------------------------------------------------ 
  2. --  Astro Smash    Coding: Eric Askilsrud (Redlense@u.washington.edu) -- 
  3. --     A <10k program written with Amos 1.3, Jun 1992                 --   
  4. --                                                                    --
  5. --             Tutorial file on AstroSmash's creation.                --     
  6. ------------------------------------------------------------------------ 
  7.  
  8.   Hey, I like the idea of the Amoner editors' for this 10k program thing.
  9. This way I can hack out fun little routines w/o having to do painstaking
  10. waste-of-my-time polishing work!
  11.  
  12.   Anyways, Astro Smash is really the first 10k of a much bigger program
  13. that I may be writing soon.  AstroSmash has a little bit of everything -
  14. and - as a bonus - it is actually playable!  So I decided to write this
  15. tutorial on it's creation for intermediate AMOS programmers!
  16.  
  17. -----------------------------------------------------------------------------
  18.  
  19.   First some background - The game uses the 8 hardware sprites, with sprites
  20. 0 and 4 being the spaceships.  The graphics are in a sprite bank that 
  21. was saved along with the program.  They were originally drawn with Dpaint in
  22. 4 color mode - it is very important that you pick up sprites from a 4 color
  23. screen, otherwise they will be treated like computed sprites until you ERASE
  24. them!   
  25.  
  26.   object
  27.    1-16    different rotations of the spaceship, w/ object 1 being a space-
  28.            ship pointing upwards, and each succesive object being the spaceship
  29.            rotated 22.5 degrees further clockwise
  30.  
  31.    17      the bullet
  32.    
  33.    18      explosion
  34.            
  35.  
  36. ----------------------------
  37. Algorithm:
  38.  
  39. setup
  40. while playing
  41.  -title screen/wait to start
  42.  while alive
  43.   for player=0 to 1
  44.    -check joystick
  45.    -update sprites
  46.   next
  47.  wend
  48.  -game over sequence
  49. wend 
  50.  
  51. ---------------------------
  52.  
  53.  
  54. Looking at the code:
  55. --------------------
  56.  
  57. >>  Dim XDIR#(1),YDIR#(1),X#(1),Y#(1),LK(1),I(1),AX#(16),AY#(16)
  58.  
  59.   This line reserves all the memory for all the arrays in the game.  An array
  60. is used for every variable that needs a seperate version for each of the two
  61. spaceships  - the index of the array represents the player number (0 & 1).
  62.  
  63.    xdir#()   - holds the horizontal component of velocity
  64.    ydir#()   - holds the vertical component of velocity
  65.    x#()      - holds x coord of ship
  66.    y#()      - holds y coord of ship
  67.    lk()      - holds the last direction the joystick was pressed
  68.    i()       - holds the image number of ship (1-16)
  69.  
  70. Notice that the '#' after x,y,xdir,ydir means that they are floating point
  71. variables - that means they contain a decimal point (see manual)
  72.  
  73.    ax#() and ay#() are used to store a table of values, they will be
  74.    explained shortly   
  75.    
  76. >>  Flash Off : Hide : Curs Off : Paper 0 : Degree 
  77.  
  78.   These commands turn the flashing off, hide the mousepointer, turn the cursor
  79. off, set the background to black, and set the trigonomic functions to degree
  80. mode(see below) respectively.
  81.  
  82. >> For ANGLE=0 To 15
  83. >>  AX#(ANGLE+1)=0.5*Sin(ANGLE*22.5)
  84. >>  AY#(ANGLE+1)=-0.5*Cos(ANGLE*22.5)
  85. >> Next 
  86.  
  87.   These statements fill the table of the aforementioned AX#() and AY#().
  88. This table is a holds the 'x-acceleration' and 'y-acceleration' for the
  89. ship for any given spaceship image number (1-16).  I've set the acceleration
  90. to .5 - We can use trigonometry to figure the x and y components of accel.
  91. For example, if the ship was thrusting 45 degrees clockwise from straight
  92. up (image#3) ax# would be .5 * sin45 and ay# would be .5 * cos45.
  93.  
  94. Notice the negative in front of the calculation for AY# - this is because
  95. 'up' on the computer screen is negative and not positive.  Negating the
  96. accel y-component will enable us to comply.
  97.  
  98. So, the loop precalculates x,y components of acceleration for each image number.
  99. Eg. ax#(3) returns accel x-component for image #3
  100.          
  101. >> Make Mask 
  102.  
  103. Make mask arround images for collision detection
  104.  
  105. >> While QUIT=0
  106.  
  107.   'Keep doing every thing between here and WEND until user quits'
  108.  
  109. >>   TYPE=0 : For Z=0 To 1 : XDIR#(Z)=0.0 : YDIR#(Z)=0.0 : Next 
  110. >>   X#(1)=10.0 : Y#(1)=10.0 : I(1)=7 : X#(0)=300.0 : Y#(0)=180.0 : I(0)=15
  111. >>   INGAME=0 : Cls 
  112.  
  113.   This initializes all the stuff for a game:
  114.  
  115.   TYPE=0  --> TYPE  holds Warp/Bounce mode - 0 means that we don't know yet
  116.   XDIR#(), YDIR#() = 0  -->  set velocity vectors to zero
  117.   x=10, y=10, etc -->  gives spaceships their starting coords
  118.   i(1)=7 i(0)=15  --> gives spaceships their initial images
  119.   INGAME=0 --> this means that nobodys died in current game yet
  120.  
  121.  
  122. >>   Locate ,2 : Centre "Astro Smash"
  123. >>   Locate ,4 : Centre "(Written in Amos 1.3)"
  124. >>   Locate ,8 : Centre "1) Reflective Walls "
  125. >>   Locate ,10 : Centre "2) Warp Space"
  126. >>   Locate ,13 : Centre "Q) Quit"
  127. >>   While TYPE=0 : A$=Inkey$ : If A$="1" Then TYPE=1
  128. >>                              If A$="2" Then TYPE=2
  129. >>                              If Upper$(A$)="Q" Then End 
  130. >>   Wend 
  131.  
  132.    This draws the game selection menu and waits for the user to enter a TYPE.
  133. Keeps getting keys until TYPE other than 0 is given, or, by the selection of
  134. 'q', the program is ended.  Notice the use of upper$, which lets it accept
  135. capital or lower-case Q's - see manual.
  136.  
  137. >>   Cls : If TYPE=1 Then Box 0,0 To 319,199
  138.  
  139.    Clears the screen and, if in a Bounce game, draw the border 
  140.  
  141. >>   While INGAME=0
  142.  
  143.   'Keep doing every thing between here and WEND until somebodys dead'
  144.  
  145. >>    For P=0 To 1
  146.  
  147.   P represents the player number - so, do each of the following for each player:
  148.  
  149. >>     K=Joy(P)
  150.  
  151.   Read the JoyStick for current P
  152.  
  153. >>     If K>15 Then K=K-16 : XDIR#(P)=XDIR#(P)+AX#(I(P)) : YDIR#(P)=YDIR#(P)+AY#(I(P)) : Gosub CHSPEED
  154.  
  155.   If K>15 that means that that player is pressing FIRE button
  156.   k=k-16 just means 'now we know the players pressed the button, and we'll take
  157.                      care of it' - subtracting 16 from k just leaves us with
  158.                      joystick direction values w/o the button (see manual)
  159.  
  160.   Since the 'thrust' was pressed, we will add the the component-acceleration
  161.   values from the AX and AY tables explained above (notice the player indexing).
  162.  
  163.         XDIR#(P)=XDIR#(P)+AX#(I(P)) : YDIR#(P)=YDIR#(P)-AY#(I(P))
  164.  
  165.   And lastly, Gosub CHSPEED which limits the spaceship from going too
  166.   fast (see explanation of routine below).
  167.  
  168. >>     If K=8 Then If Chanan(P)=0 Then I(P)=I(P)+1 : Gosub CHLOOP : Amal P*4,"A2,("+Str$(I(P))+",1)" : Amal On P*4
  169.  
  170.   If K=8 that means that the player is pressing right on the joystick,
  171.   which means that the spaceship should be rotated right - meaning image
  172.   number is increased - but what if we are at image 16 (337.5 degrees) and
  173.   we rotate 22.5 degrees further?  Since 360 degrees = 0 degrees, we switch
  174.   back to image number 1 - this is exactly what Gosub CHLOOP performs.
  175.   Once we figure out what new Image the sprite should be, we set up an AMAL
  176.   string to Animate it to that image - Why all this Chanan (see manual!!)
  177.   and AMAL stuff? why not just change the sprite? Because that would make the
  178.   ship rotate too fast!  So, we say with an amal string, to change the image
  179.   number in 2 vbl's - With the Chanan(P) function check that the image is not
  180.   being animated before incrementing the image!
  181.  
  182.   Amal P*4,"A2,("+Str$(I(P))+",1)"
  183.  
  184.                      ^^ this little tricky string addition trick,
  185.                         the string is seen as:
  186.  
  187.                         "A2,(#,1)"  where # represents the image number to
  188.                                     animate to.
  189.  
  190.   Expirement with this trick of using the str$() function to create amal
  191.   strings!!!  This method is much better than writing independent amal strings
  192.   for small speed or distance differences OR by using the Amreg function
  193.   to pass it along!!
  194.  
  195. >>     If K=4 Then If Chanan(P)=0 Then I(P)=I(P)-1 : Gosub CHLOOP : Amal P*4,"A2,("+Str$(I(P))+",1)" : Amal On P*4
  196.  
  197.   This is the same story as the line before, except this time we are dealing with
  198.   joystick left
  199.  
  200. >>     If K=1 and LK(P)<>K Then Gosub BULLET
  201.  
  202.   If the joystick is pressed up AND the last direction the joystick was pressed
  203.   was NOT up (to ensure only ONE bullet is released every time the joystick
  204.   is pressed up) then Gosub BULLET (see below).
  205.  
  206. >>     On TYPE Gosub BOUNCE,WARP
  207.  
  208.   Now depending on the type of game do either 1) bounce off walls 2) warp to
  209.   other side of screen  (see below)
  210.  
  211. >>     X#(P)=XDIR#(P)+X#(P) : Y#(P)=YDIR#(P)+Y#(P)
  212.  
  213.   After getting the joystick info, we can now finally update the sprites.
  214.   The new x coord will equal the old one plus the x-comp of velocity(xdir)
  215.   The new y coord will equal the old one plus the y-comp of velocity(ydir)
  216.  
  217. >>     Sprite P*4,X Hard(X#(P)),Y Hard(Y#(P)),I(P)
  218.  
  219.   Put the sprite in its place - Sprite 0 is used for player 0
  220.                                 Sprite 4 is used for player 1
  221.   Therefore there is a neat little formula that gives sprite number given
  222.   player number: player# * 4 !!! (wow)
  223.  
  224.   Notice the current player index is accessed for x,y and i 
  225.  
  226. >>     Gosub CHECKBULLS
  227.  
  228.   Also we should check to make sure their are no bullets standing still on
  229.   the playfield (see below)
  230.  
  231. >>     LK(P)=K
  232.  
  233.   store the current k into 'last k' (lk) for that player
  234.   this is used by the fire bullet routine (see above)
  235.  
  236. >>     If Sprite Col(P*4)<>0 Then Boom : Sprite P*4,X Hard(X#(P)),Y Hard(Y#(P)),18 : INGAME=1 : Amal Off 
  237.  
  238.   Check for sprite collisions - sprite number for collision detection is
  239.   calculated from our previously derived formula, sprite# = p*4.
  240.  
  241.   If there is a collision, then make a Boom sound,
  242.   change that sprite image into an explosion! (image 18)
  243.   turn amal off, and let the WHILE loop know that somebody has died (ingame=1)
  244.  
  245. >>    Next 
  246.  
  247.   End of 'Player' loop...
  248.  
  249. >>     Wait Vbl 
  250.  
  251.   Wait a Vbl to wait for screen to draw
  252.  
  253. >>   Wend 
  254.  
  255.   Once we get passed this WEND, that means that somebody has DIED!
  256.  
  257. >>   For Z=0 To 1
  258. >>    If Sprite Col(Z*4)<>0 Then Sprite Z*4,X Hard(X#(Z)),Y Hard(Y#(Z)),18
  259. >>   Next 
  260.  
  261.   Check Collision of the two spaceships once more, just incase they collided
  262.   into one another - otherwise only one would turn into an explosion.
  263.   If there is a collision, turn that sprite into an explosion image #18 as
  264.   above
  265.  
  266. >>   Sprite Update : Wait Vbl : Locate ,11 : Centre "Game Over" : Wait 40 : While Joy(1)<16 : Wend 
  267.  
  268.   This is more end-of-game stuff - update the sprites to ensure they show an
  269.   explosion, print 'game over', wait for player 1 to press his button 
  270.  
  271. >>   For Z=0 To 7 : Sprite Off Z : Next : Sprite Update 
  272.  
  273.   Finally, turn all the sprites off, as we are done with them for this game
  274.  
  275. >> Wend 
  276. >> End
  277.  
  278.   Once we are out of this WEND, that means the person has quit!!
  279.   Which means the next command is End!
  280.  
  281. --------------------------------
  282. Routines called by the main loop
  283. --------------------------------
  284.  
  285. >> CHLOOP:
  286. >>  If I(P)>16 Then I(P)=1
  287. >>  If I(P)<1 Then I(P)=16
  288. >> Return 
  289.  
  290.   This routine sets image# back to 1 if it gets greater than 16
  291.   and up to 16 if it gets below image number 1 (see above)
  292.  
  293. >> CHSPEED:
  294. >>  If XDIR#(P)>4.0 Then XDIR#(P)=4.0
  295. >>  If XDIR#(P)<-4.0 Then XDIR#(P)=-4.0
  296. >>  If YDIR#(P)>4.0 Then YDIR#(P)=4.0
  297. >>  If YDIR#(P)<-4.0 Then YDIR#(P)=-4.0
  298. >> Return 
  299.  
  300.   This routine limits how big or small a component of velocity can be.
  301.   You can see that if the absolute value of the component of speed is
  302.   greater than 4 it is set back to 4.
  303.  
  304. >> BOUNCE:
  305. >>  If X#(P)>304.0 Then X#=304.0 : XDIR#(P)=0.0-XDIR#(P) : Bell 1
  306. >>  If X#(P)<-3.0 Then X#=-3.0 : XDIR#(P)=0.0-XDIR#(P) : Bell 1
  307. >>  If Y#(P)>184.0 Then Y#=184.0 : YDIR#(P)=0.0-YDIR#(P) : Bell 1
  308. >>  If Y#(P)<-2.0 Then Y#=-2.0 : YDIR#(P)=0.0-YDIR#(P) : Bell 1
  309. >> Return 
  310.  
  311.   This routine is used by the Bounce mode of the game - if the x or y
  312.   components of the ships go off the screen, then the velocity-component that
  313.   is perpendicular to that of the boundary it exceeds is reversed.  
  314.   If such a collision is detected, the awesome 'Bell 1' sound effect is
  315.   executed for that extra arcade realism.
  316.  
  317. >> WARP:
  318. >>  If X#(P)>304.0 Then X#(P)=0.0
  319. >>  If X#(P)<0.0 Then X#(P)=304.0
  320. >>  If Y#(P)>184.0 Then Y#(P)=0.0
  321. >>  If Y#(P)<0.0 Then Y#(P)=184.0
  322. >> Return 
  323.  
  324.   This routine is used by the Warp mode of the game - if the x or y
  325.   components exceed the maximum in the region, they are set to the minimum
  326.   and vise versa.
  327.  
  328. >> BULLET:
  329. >>  Q=0
  330. >>  If P=0 Then For Z=1 To 3 : If Chanmv(Z)=0 Then Q=Z : Next 
  331. >>  If P=1 Then For Z=5 To 7 : If Chanmv(Z)=0 Then Q=Z : Next 
  332.  
  333.   The Bullet routine is called whenever the joystick is pressed up again -
  334.   First we must cycle thru the bullet Sprites that belong to the current
  335.   player, to see if any are stationary - which means they are not on the
  336.   screen and can be used.
  337.  
  338.   Sprites 1 to 3 are bullets belonging to player0
  339.   sprites 5 to 8 are bullets belonging to player1
  340.  
  341.   q holds the last found currently-available bullet - It is initially set
  342.   to zero, therefore, if no bullets are found it is left 0
  343.  
  344. >>  If Q=0 Then Return 
  345. >>  Shoot 
  346.  
  347.   So, if no bullets are available, RETURN (do nothing)
  348.   Otherwise, make the neat 'Shoot' sound fx, and do the following:
  349.  
  350. >>  Sprite Q,X Hard(X#(P)+7)+30*AX#(I(P)),Y Hard(Y#(P)+8)+30*AY#(I(P)),17
  351.  
  352.   This command gives the bullet its initial position.  The initial position
  353.   is going to be the ships x,y plus a displacement value (x+7,y+8) that gives
  354.   the coordinate of the center of the ship.  To the center of the ship's coords
  355.   are added multiple of the  vector that points in the direction of the
  356.   ship ---- the components of this vector are the same as that of the accel
  357.   vector, our good buddies AX and AY!  To initially get the bullet good and
  358.   far away from the ship, this vector is multiplied by 30 (determined expire-
  359.   mentally).
  360.  
  361.   Image number 17 is assigned, as this is the 'bullet' object
  362.  
  363.  
  364. >>  Amal Q,"M "+Str$(Int(300*AX#(I(P))))+","+Str$(Int(300*AY#(I(P))))+",50" : Amal On Q
  365.  
  366.   This gives the bullet its Movement command.  Again, this uses string addition
  367.   to produce the AMAL string.  Looks pretty gross, don't it??
  368.   
  369.   What it basically does is:  "M 300*ax(i),300*ay(i),50" 
  370.   which means Move (in 50 vbl's) : 300 times the x-comp of accel in the x-
  371.   direction,  and 300 times the y-comp of accel in the y-direction.
  372.  
  373.   The reason for all those parethesis is:
  374.   1)  We have them around the Str$(),
  375.   2)  We use Int() around the string to Str$() - this is because AMAL does't
  376.       like floats - so we must convert the numbers to Str$() into integers  
  377.   3)  player indexing
  378.  
  379.  
  380.   Hopefully it isn't too mind boggeling - Remember, when looking at things
  381.   like this it is very helpful to watch your order of operations - start
  382.   from the inside of the parenthesis and work your way out
  383.  
  384.   EX)
  385.  
  386.   Amal Q,"M "+Str$(Int(300*AX#(I(P))))+","+Str$(Int(300*AY#(I(P))))+",50"
  387.  
  388.   AMAL Q,"M " + Str$(Int(300*ax#(2))) + "," + Str$(Int(300*AY#(2))) + ",50"
  389.  
  390.   AMAL Q,"M " +  Str$(Int(300*.38))   + "," + Str$(Int(300 * .92))  + ",50"
  391.  
  392.   AMAL Q,"M " +  Str$(114)            + "," + str$(276)              + ",50"
  393.  
  394.   AMAL Q,"M " +  "114"                + "," + "276"                  + ",50"
  395.  
  396.   AMAL Q,"M 114,276,50"
  397.  
  398. >> Return 
  399.  
  400.  
  401. >> CHECKBULLS:
  402. >> For Z=1 To 7
  403. >>  If Z<>4 and Chanmv(Z)=0 Then Sprite Off Z
  404. >> Next 
  405. >> Return 
  406.  
  407.   This routine makes sure that there are no bullets standing still on the play-
  408.   feild.  Bullets are given a starting location and a certain movement string by
  409.   the BULLET routine above - but there is nothing clearing them once their
  410.   movement pattern runs out.  This checks each of the sprites 1-7 except 4
  411.   (sprites 0 and 4 are ships) to see if they are moving with the Chanmv command
  412.   (see manual).  If they are not moving, this routine just turns the sprite off.
  413.  
  414.  
  415. -------------------------------------------------------------------------------
  416.  
  417. Okay, that's it! Hopefully that's been of some interest to you.
  418. Why don't you drop me a line and let me know what you think,
  419. (don't tell me I spel bad or nuthin grammer like)
  420.  
  421.                        Thanks,
  422.                                 -Eric  (redlense@milton.u.washington.edu)
  423.