home *** CD-ROM | disk | FTP | other *** search
/ Mac Mania 2 / MacMania 2.toast / Demo's / Tools&Utilities / Programming / FBSpriteWorld 1.05b / Examples 1.01b / SWSimpleBreakOut.main next >
Encoding:
Text File  |  1994-05-10  |  10.5 KB  |  332 lines  |  [TEXT/ZBAS]

  1. 'SWSimpleBreakOut.main by Robert Hommel
  2. '© Copyright 1994
  3. 'All rights granted for any use whatsoever
  4.  
  5. 'This simple game sample is based on the classic game "Break Out."
  6. 'Though incomplete, it demonstrates a number of important FBSprite-
  7. 'World concepts: collision detection, large numbers of inactive
  8. 'Sprites, and custom movement procedures (note the paddle moveProc,
  9. 'in particular, which allows you to control a Sprite with the mouse).
  10.  
  11. 'Dispite its lack of important game elements like sound, scoring, 
  12. 'levels, etc., it demonstrates the usefulness and feasibility of
  13. 'FBSpriteWorld for this type of game.
  14.  
  15. 'Disclaimer:  I've tested these routines quite thoroughly on my Mac
  16. 'LC running System 7.01 and FB 1.02c.  I make no promises or warranties 
  17. 'of any kind.
  18. '*********************************************************************
  19.  
  20. COMPILE 0, _MacsBugLabels _caseInsensitive
  21. RESOURCES "FBSpriteWorld.RSRC"
  22.  
  23. '---------------------------- GLOBALS --------------------------------
  24.  
  25. '--GLOBALS "GraphicUtils.glbl"
  26. GLOBALS "FBSpriteWorld.glbl"
  27.  
  28. _backPatRSRC=128
  29. _brickRSRC=500
  30. _ballRSRC=510
  31. _ballY=60
  32. _paddleRSRC=520
  33. _paddleY=260
  34. _paddleWidth=43
  35.  
  36. DIM gBallCounter                                  'ball counter
  37. DIM gPnt.4                                        'point var for paddle move proc
  38.  
  39. END GLOBALS
  40.  
  41. GOTO "Main"
  42.  
  43. '--------------------------- INCLUDES --------------------------------
  44.  
  45. INCLUDE "FBSpriteWorld.incl"
  46.  
  47. '------------------------- ERROR HANDLER -----------------------------
  48.  
  49. CLEAR LOCAL
  50. LOCAL FN FatalError(errCode)
  51.    'Simple error handler.  You'll want to improve on this in your
  52.    'program...
  53.    
  54.    LONG IF errCode<>_noErr
  55.       SELECT errCode
  56.          CASE _swTooManyLayers:errStr$="Out of Memory."
  57.          CASE _swTooManySprites:errStr$="Too many Sprites."
  58.          CASE _swTooManyFrames:errStr$="Too many Frames."
  59.          CASE _swNotSystemSeven:errStr$="SpriteWorld requires System 7!"
  60.          CASE _swTimeMgrNotPresent:errStr$="SpriteWorld requires Time Manager."
  61.          CASE _swOutOfMemory:errStr$="Out of Memory."
  62.          CASE ELSE
  63.             errStr$="Unknown error."
  64.       END SELECT
  65.       
  66.       tmp$="Error Code:"+STR$(errCode)
  67.       CALL PARAMTEXT(errStr$,tmp$,"","")
  68.       x=FN STOPALERT(1,0)
  69.       END
  70.    END IF
  71. END FN
  72.  
  73. '------------------------ SPRITEWORLD PROCS --------------------------
  74.  
  75. "BallMoveProc"
  76. ENTERPROC(SWPtr&,spritePtr&,curRectPtr&)
  77.    'Variation of standard bounce movement proc.  Keeps sprite inside 
  78.    'sprite boundsRect, unless sprite touches bottom boundary, in which
  79.    'case gSpritesPlayed is incremented and the ball sprite returns to
  80.    'its original position.
  81.    
  82.    LONG IF {curRectPtr&+_left}+{spritePtr&+_xDelta}<={spritePtr&+_sBoundsRect+_left}
  83.       POKE WORD spritePtr&+_xDelta,{spritePtr&+_xDelta}*-1
  84.    XELSE
  85.       LONG IF {curRectPtr&+_right}+{spritePtr&+_xDelta}>={spritePtr&+_sBoundsRect+_right}
  86.          POKE WORD spritePtr&+_xDelta,{spritePtr&+_xDelta}*-1
  87.       END IF
  88.    END IF
  89.    LONG IF {curRectPtr&+_top}+{spritePtr&+_yDelta}<={spritePtr&+_sBoundsRect+_top}
  90.       POKE WORD spritePtr&+_yDelta,{spritePtr&+_yDelta}*-1
  91.    XELSE
  92.       LONG IF {curRectPtr&+_bottom}+{spritePtr&+_yDelta}>={spritePtr&+_sBoundsRect+_bottom}
  93.          BEEP
  94.          FN SWMoveSprite(SpritePtr&,0,_ballY)
  95.          FN SWSetMoveDelta(SpritePtr&,2,2)
  96.          INC(gBallCounter)
  97.       END IF
  98.    END IF
  99. EXITPROC
  100. RETURN
  101.  
  102. "BallCollideProc"
  103. ENTERPROC(ballSpritePtr&,brickSpritePtr&,sectRectPtr&)
  104.    LONG IF brickSpritePtr&.isVisible%
  105.       FN SWSetSpriteVisible(brickSpritePtr&,_false)
  106.       ballSpritePtr&.yDelta%=ballSpritePtr&.yDelta%*-1
  107.    END IF
  108. EXITPROC
  109. RETURN
  110.  
  111. "PaddleMoveProc"
  112. ENTERPROC(SWPtr&,spritePtr&,curRectPtr&)
  113.    'move paddle left or right based on mouse movement
  114.    CALL GETMOUSE(gPnt)
  115.        LONG IF gPnt.h<spritePtr&.sBoundsRect.left%
  116.       FN SWMoveSprite(spritePtr&,spritePtr&.sBoundsRect.left%,_paddleY)
  117.        XELSE 
  118.       LONG IF gPnt.h>spritePtr&.sBoundsRect.right%-_paddleWidth
  119.                  FN SWMoveSprite(spritePtr&,spritePtr&.sBoundsRect.right%-_paddleWidth,_paddleY)
  120.           XELSE
  121.                  FN SWMoveSprite(spritePtr&,gPnt.h,_paddleY)
  122.       END IF
  123.    END IF
  124. EXITPROC
  125. RETURN
  126.  
  127. "PaddleCollideProc"
  128. ENTERPROC(paddleSpritePtr&,ballSpritePtr&,sectRectPtr&)
  129.    'add paddle's movement to ball
  130.    LONG IF paddleSpritePtr&.currentRect.left%<>paddleSpritePtr&.oldRect.left%
  131.       IF ballSpritePtr&.xDelta%<0 THEN ballDelta=ballSpritePtr&.xDelta%-1 ELSE ballDelta=ballSpritePtr&.xDelta%+1
  132.       FN SWSetMoveDelta(ballSpritePtr&,ballDelta,2)
  133.    END IF
  134.    ballSpritePtr&.yDelta%=ballSpritePtr&.yDelta%*-1
  135. EXITPROC
  136. RETURN
  137.  
  138. "SWTimeTask"
  139. 'Sets the frameTTHasFired or moveTTHasFired field of the sprite record
  140. 'to _zTrue (-1).  Called by the Time Manager if frameTimeInterval or
  141. 'moveTimeInterval field of sprite record > 0.
  142.  
  143. `                 move.w      #-1,tmXQSize(a1)  ;[move|frame]TTHasFired=_zTrue
  144. `                 rts                           ;return
  145.  
  146. '-------------------------- MAIN PROGRAM ----------------------------
  147.  
  148. "Main"
  149. DIM wRect.8
  150. DIM mySW.SpriteWorldRec
  151. DIM brickLayer.SWLayerRec,ballLayer.SWLayerRec,paddleLayer.SWLayerRec
  152. DIM brickSprite.SWSpriteRec(9),ballSprite.SWSpriteRec,paddleSprite.SWSpriteRec
  153. DIM brickFrame.SWFrameRec,ballFrame.SWFrameRec,paddleFrame.SWFrameRec
  154. DIM wndPort&
  155.  
  156. CURSOR _watchCursor                               'wait a second while we set up                             
  157. gSpritesPlayed=0                                  'intialize ball counter
  158.  
  159. '--------------------------------------------------------------------
  160. 'Initialization and Set Up
  161. '--------------------------------------------------------------------
  162.  
  163. 'Can we run in this environment?
  164. err=FN SWEnterSpriteWorld
  165. FN FatalError(err)                                 
  166.  
  167. 'Open a window and draw pretty background
  168. pat&=FN GETPIXPAT(_backPatRSRC)                   'get pattern RSRC
  169. CALL SETRECT(wRect,0,0,180,300)                   'set our window rect
  170. WINDOW #1,"SimpleBreakOut",@wRect,5               'open a window the same size as wRect
  171. wndPort&=FN GetCurrPort                           'get grafPtr
  172. CALL FILLCRECT(#wndPort&+_portRect,pat&)          'fill with nice pattern
  173.  
  174. 'Create SpriteWorld based on window port
  175. err=FN SWCreateSWFromWindow(@mySW,wndPort&)
  176. FN FatalError(err)
  177.  
  178. 'Get time task ptr (same for all sprites)
  179. ttPtr&=LINE "SWTimeTask"
  180.  
  181. '--------------------------------------------------------------------
  182. 'Ball Sprite, Frame, and Layer
  183. '--------------------------------------------------------------------
  184.  
  185. 'Create ball sprite
  186. movePtr&=LINE "BallMoveProc"
  187. err=FN SWSpriteFromPict(@ballSprite,0,0,_ballY,wndPort&+_portRect,_zTrue,2,2,-1,ttPtr&,movePtr&,_ballRSRC)
  188. FN FatalError(err)
  189.  
  190. 'Frame time <0 means we don't change frames
  191. FN SWSetFrameTime(@ballSprite,-1)
  192.  
  193. 'Set move time
  194. FN SWSetMoveTime(@ballSprite,35)
  195.  
  196. 'Create ball frame from PICT resource
  197. err=FN SWFrameFromPict(@ballFrame,_ballRSRC)
  198. FN FatalError(err)
  199.  
  200. 'Set collide proc
  201. collidePtr&=LINE "BallCollideProc"
  202. FN SWSetCollideProc(@ballSprite,collidePtr&)
  203.  
  204. 'Put it all together
  205. err=FN SWAddFrameToSprite(@ballSprite,@ballFrame)
  206. FN FatalError(err)
  207. err=FN SWAddSpriteToLayer(@ballLayer,@ballSprite)
  208. FN FatalError(err)
  209. err=FN SWAddLayerToWorld(@mySW,@ballLayer)
  210. FN FatalError(err)
  211.  
  212. '--------------------------------------------------------------------
  213. 'Brick Sprites, Frame, and Layer
  214. '--------------------------------------------------------------------
  215.  
  216. 'Create first brick sprite
  217. movePtr&=_nil                                     'sprite won't be moving
  218. err=FN SWSpriteFromPict(@brickSprite(0),0,0,20,wndPort&+_portRect,_zTrue,2,2,-1,ttPtr&,movePtr&,_brickRSRC)
  219. FN FatalError(err)
  220.  
  221. 'Create frame from PICT resource
  222. err=FN SWFrameFromPict(@brickFrame,_brickRSRC)
  223. FN FatalError(err)
  224.  
  225. 'Add frame to sprite (we add the frame now so the clones will contain it, too
  226. err=FN SWAddFrameToSprite(@brickSprite(0),@brickFrame)
  227. FN FatalError(err)
  228.  
  229. 'Clone 9 more bricks
  230. FOR x=1 TO 9
  231.    FN SWCloneSprite(@brickSprite(0),@brickSprite(x),ttPtr&)
  232. NEXT
  233.  
  234. 'Set brick locations
  235. FOR x=1 TO 4
  236.    FN SWSetSpriteLocation(@brickSprite(x),(x-1)*37+37,20)
  237. NEXT
  238.  
  239. FOR x=1 TO 5
  240.    FN SWSetSpriteLocation(@brickSprite(x+4),(x-1)*37,40)
  241. NEXT
  242.  
  243. 'Set frame and move times
  244. FOR x=0 TO 9
  245.    'Frame time <0 means we don't change frames
  246.    FN SWSetFrameTime(@brickSprite(x),-1)
  247.    'Move time <0 means we don't move sprite
  248.    FN SWSetMoveTime(@brickSprite(x),-1)
  249. NEXT
  250.  
  251. 'Put it together
  252. FOR x=0 TO 9
  253.    err=FN SWAddSpriteToLayer(@brickLayer,@brickSprite(x))
  254.    FN FatalError(err)
  255. NEXT
  256.  
  257. err=FN SWAddLayerToWorld(@mySW,@brickLayer)
  258. FN FatalError(err)
  259.  
  260. '--------------------------------------------------------------------
  261. 'Paddle Sprite, Frame, and Layer
  262. '--------------------------------------------------------------------
  263.  
  264. 'Create paddle sprite
  265. movePtr&=LINE "PaddleMoveProc"
  266. err=FN SWSpriteFromPict(@paddleSprite,0,0,_paddleY,wndPort&+_portRect,_zTrue,2,2,-1,ttPtr&,movePtr&,_paddleRSRC)
  267. FN FatalError(err)
  268.  
  269. 'Frame time <0 means we don't change frames
  270. FN SWSetFrameTime(@paddleSprite,-1)
  271.  
  272. 'Create paddle frame from PICT resource
  273. err=FN SWFrameFromPict(@paddleFrame,_paddleRSRC)
  274. FN FatalError(err)
  275.  
  276. 'Set collide proc
  277. collidePtr&=LINE "PaddleCollideProc"
  278. FN SWSetCollideProc(@paddleSprite,collidePtr&)
  279.  
  280. 'Put it all together
  281. err=FN SWAddFrameToSprite(@paddleSprite,@paddleFrame)
  282. FN FatalError(err)
  283. err=FN SWAddSpriteToLayer(@paddleLayer,@paddleSprite)
  284. FN FatalError(err)
  285. err=FN SWAddLayerToWorld(@mySW,@paddleLayer)
  286. FN FatalError(err)
  287.  
  288. '--------------------------------------------------------------------
  289. 'Final Set Up
  290. '--------------------------------------------------------------------
  291.  
  292. 'Prepare loadframe for animation
  293. FN SWRefreshBackground(@mySW)
  294.  
  295. CALL HIDECURSOR                                   'we're ready to go...
  296.  
  297. 'Render first frame of animation
  298. FN SWAnimateSpriteWorld(@mySW)
  299.  
  300. '--------------------------------------------------------------------
  301. 'Animation Loop
  302. '--------------------------------------------------------------------
  303.  
  304. DO
  305.    'process normal sprite movement
  306.    FN SWProcessSpriteWorld(@mySW)
  307.    'is game over?
  308.    LONG IF gBallCounter=4
  309.       BEEP:BEEP:BEEP
  310.       GOTO "Finish Up"
  311.    END IF
  312.    'check to see if ball collided with bricks
  313.    FN SWCollideSpriteLayer(@ballLayer,@brickLayer)
  314.    'check to see if paddle collided with ball
  315.    FN SWCollideSpriteLayer(@paddleLayer,@ballLayer)
  316.    'draw sprites on screen
  317.    FN SWAnimateSpriteWorld(@mySW)
  318.    CALL SYSTEMTASK
  319. UNTIL FN BUTTON
  320.  
  321. '--------------------------------------------------------------------
  322. 'Dispose SpriteWorld & Exit
  323. '--------------------------------------------------------------------
  324. "Finish Up"
  325. err=FN SWDisposSpriteWorld(@mySW)
  326. FN FatalError(err)
  327.  
  328. CALL INITCURSOR                                   'reset cursor
  329.  
  330. END
  331.  
  332.