home *** CD-ROM | disk | FTP | other *** search
Text File | 1994-05-10 | 10.5 KB | 332 lines | [TEXT/ZBAS] |
- 'SWSimpleBreakOut.main by Robert Hommel
- '© Copyright 1994
- 'All rights granted for any use whatsoever
-
- 'This simple game sample is based on the classic game "Break Out."
- 'Though incomplete, it demonstrates a number of important FBSprite-
- 'World concepts: collision detection, large numbers of inactive
- 'Sprites, and custom movement procedures (note the paddle moveProc,
- 'in particular, which allows you to control a Sprite with the mouse).
-
- 'Dispite its lack of important game elements like sound, scoring,
- 'levels, etc., it demonstrates the usefulness and feasibility of
- 'FBSpriteWorld for this type of game.
-
- 'Disclaimer: I've tested these routines quite thoroughly on my Mac
- 'LC running System 7.01 and FB 1.02c. I make no promises or warranties
- 'of any kind.
- '*********************************************************************
-
- COMPILE 0, _MacsBugLabels _caseInsensitive
- RESOURCES "FBSpriteWorld.RSRC"
-
- '---------------------------- GLOBALS --------------------------------
-
- '--GLOBALS "GraphicUtils.glbl"
- GLOBALS "FBSpriteWorld.glbl"
-
- _backPatRSRC=128
- _brickRSRC=500
- _ballRSRC=510
- _ballY=60
- _paddleRSRC=520
- _paddleY=260
- _paddleWidth=43
-
- DIM gBallCounter 'ball counter
- DIM gPnt.4 'point var for paddle move proc
-
- END GLOBALS
-
- GOTO "Main"
-
- '--------------------------- INCLUDES --------------------------------
-
- INCLUDE "FBSpriteWorld.incl"
-
- '------------------------- ERROR HANDLER -----------------------------
-
- CLEAR LOCAL
- LOCAL FN FatalError(errCode)
- 'Simple error handler. You'll want to improve on this in your
- 'program...
-
- LONG IF errCode<>_noErr
- SELECT errCode
- CASE _swTooManyLayers:errStr$="Out of Memory."
- CASE _swTooManySprites:errStr$="Too many Sprites."
- CASE _swTooManyFrames:errStr$="Too many Frames."
- CASE _swNotSystemSeven:errStr$="SpriteWorld requires System 7!"
- CASE _swTimeMgrNotPresent:errStr$="SpriteWorld requires Time Manager."
- CASE _swOutOfMemory:errStr$="Out of Memory."
- CASE ELSE
- errStr$="Unknown error."
- END SELECT
-
- tmp$="Error Code:"+STR$(errCode)
- CALL PARAMTEXT(errStr$,tmp$,"","")
- x=FN STOPALERT(1,0)
- END
- END IF
- END FN
-
- '------------------------ SPRITEWORLD PROCS --------------------------
-
- "BallMoveProc"
- ENTERPROC(SWPtr&,spritePtr&,curRectPtr&)
- 'Variation of standard bounce movement proc. Keeps sprite inside
- 'sprite boundsRect, unless sprite touches bottom boundary, in which
- 'case gSpritesPlayed is incremented and the ball sprite returns to
- 'its original position.
-
- LONG IF {curRectPtr&+_left}+{spritePtr&+_xDelta}<={spritePtr&+_sBoundsRect+_left}
- POKE WORD spritePtr&+_xDelta,{spritePtr&+_xDelta}*-1
- XELSE
- LONG IF {curRectPtr&+_right}+{spritePtr&+_xDelta}>={spritePtr&+_sBoundsRect+_right}
- POKE WORD spritePtr&+_xDelta,{spritePtr&+_xDelta}*-1
- END IF
- END IF
- LONG IF {curRectPtr&+_top}+{spritePtr&+_yDelta}<={spritePtr&+_sBoundsRect+_top}
- POKE WORD spritePtr&+_yDelta,{spritePtr&+_yDelta}*-1
- XELSE
- LONG IF {curRectPtr&+_bottom}+{spritePtr&+_yDelta}>={spritePtr&+_sBoundsRect+_bottom}
- BEEP
- FN SWMoveSprite(SpritePtr&,0,_ballY)
- FN SWSetMoveDelta(SpritePtr&,2,2)
- INC(gBallCounter)
- END IF
- END IF
- EXITPROC
- RETURN
-
- "BallCollideProc"
- ENTERPROC(ballSpritePtr&,brickSpritePtr&,sectRectPtr&)
- LONG IF brickSpritePtr&.isVisible%
- FN SWSetSpriteVisible(brickSpritePtr&,_false)
- ballSpritePtr&.yDelta%=ballSpritePtr&.yDelta%*-1
- END IF
- EXITPROC
- RETURN
-
- "PaddleMoveProc"
- ENTERPROC(SWPtr&,spritePtr&,curRectPtr&)
- 'move paddle left or right based on mouse movement
- CALL GETMOUSE(gPnt)
- LONG IF gPnt.h<spritePtr&.sBoundsRect.left%
- FN SWMoveSprite(spritePtr&,spritePtr&.sBoundsRect.left%,_paddleY)
- XELSE
- LONG IF gPnt.h>spritePtr&.sBoundsRect.right%-_paddleWidth
- FN SWMoveSprite(spritePtr&,spritePtr&.sBoundsRect.right%-_paddleWidth,_paddleY)
- XELSE
- FN SWMoveSprite(spritePtr&,gPnt.h,_paddleY)
- END IF
- END IF
- EXITPROC
- RETURN
-
- "PaddleCollideProc"
- ENTERPROC(paddleSpritePtr&,ballSpritePtr&,sectRectPtr&)
- 'add paddle's movement to ball
- LONG IF paddleSpritePtr&.currentRect.left%<>paddleSpritePtr&.oldRect.left%
- IF ballSpritePtr&.xDelta%<0 THEN ballDelta=ballSpritePtr&.xDelta%-1 ELSE ballDelta=ballSpritePtr&.xDelta%+1
- FN SWSetMoveDelta(ballSpritePtr&,ballDelta,2)
- END IF
- ballSpritePtr&.yDelta%=ballSpritePtr&.yDelta%*-1
- EXITPROC
- RETURN
-
- "SWTimeTask"
- 'Sets the frameTTHasFired or moveTTHasFired field of the sprite record
- 'to _zTrue (-1). Called by the Time Manager if frameTimeInterval or
- 'moveTimeInterval field of sprite record > 0.
-
- ` move.w #-1,tmXQSize(a1) ;[move|frame]TTHasFired=_zTrue
- ` rts ;return
-
- '-------------------------- MAIN PROGRAM ----------------------------
-
- "Main"
- DIM wRect.8
- DIM mySW.SpriteWorldRec
- DIM brickLayer.SWLayerRec,ballLayer.SWLayerRec,paddleLayer.SWLayerRec
- DIM brickSprite.SWSpriteRec(9),ballSprite.SWSpriteRec,paddleSprite.SWSpriteRec
- DIM brickFrame.SWFrameRec,ballFrame.SWFrameRec,paddleFrame.SWFrameRec
- DIM wndPort&
-
- CURSOR _watchCursor 'wait a second while we set up
- gSpritesPlayed=0 'intialize ball counter
-
- '--------------------------------------------------------------------
- 'Initialization and Set Up
- '--------------------------------------------------------------------
-
- 'Can we run in this environment?
- err=FN SWEnterSpriteWorld
- FN FatalError(err)
-
- 'Open a window and draw pretty background
- pat&=FN GETPIXPAT(_backPatRSRC) 'get pattern RSRC
- CALL SETRECT(wRect,0,0,180,300) 'set our window rect
- WINDOW #1,"SimpleBreakOut",@wRect,5 'open a window the same size as wRect
- wndPort&=FN GetCurrPort 'get grafPtr
- CALL FILLCRECT(#wndPort&+_portRect,pat&) 'fill with nice pattern
-
- 'Create SpriteWorld based on window port
- err=FN SWCreateSWFromWindow(@mySW,wndPort&)
- FN FatalError(err)
-
- 'Get time task ptr (same for all sprites)
- ttPtr&=LINE "SWTimeTask"
-
- '--------------------------------------------------------------------
- 'Ball Sprite, Frame, and Layer
- '--------------------------------------------------------------------
-
- 'Create ball sprite
- movePtr&=LINE "BallMoveProc"
- err=FN SWSpriteFromPict(@ballSprite,0,0,_ballY,wndPort&+_portRect,_zTrue,2,2,-1,ttPtr&,movePtr&,_ballRSRC)
- FN FatalError(err)
-
- 'Frame time <0 means we don't change frames
- FN SWSetFrameTime(@ballSprite,-1)
-
- 'Set move time
- FN SWSetMoveTime(@ballSprite,35)
-
- 'Create ball frame from PICT resource
- err=FN SWFrameFromPict(@ballFrame,_ballRSRC)
- FN FatalError(err)
-
- 'Set collide proc
- collidePtr&=LINE "BallCollideProc"
- FN SWSetCollideProc(@ballSprite,collidePtr&)
-
- 'Put it all together
- err=FN SWAddFrameToSprite(@ballSprite,@ballFrame)
- FN FatalError(err)
- err=FN SWAddSpriteToLayer(@ballLayer,@ballSprite)
- FN FatalError(err)
- err=FN SWAddLayerToWorld(@mySW,@ballLayer)
- FN FatalError(err)
-
- '--------------------------------------------------------------------
- 'Brick Sprites, Frame, and Layer
- '--------------------------------------------------------------------
-
- 'Create first brick sprite
- movePtr&=_nil 'sprite won't be moving
- err=FN SWSpriteFromPict(@brickSprite(0),0,0,20,wndPort&+_portRect,_zTrue,2,2,-1,ttPtr&,movePtr&,_brickRSRC)
- FN FatalError(err)
-
- 'Create frame from PICT resource
- err=FN SWFrameFromPict(@brickFrame,_brickRSRC)
- FN FatalError(err)
-
- 'Add frame to sprite (we add the frame now so the clones will contain it, too
- err=FN SWAddFrameToSprite(@brickSprite(0),@brickFrame)
- FN FatalError(err)
-
- 'Clone 9 more bricks
- FOR x=1 TO 9
- FN SWCloneSprite(@brickSprite(0),@brickSprite(x),ttPtr&)
- NEXT
-
- 'Set brick locations
- FOR x=1 TO 4
- FN SWSetSpriteLocation(@brickSprite(x),(x-1)*37+37,20)
- NEXT
-
- FOR x=1 TO 5
- FN SWSetSpriteLocation(@brickSprite(x+4),(x-1)*37,40)
- NEXT
-
- 'Set frame and move times
- FOR x=0 TO 9
- 'Frame time <0 means we don't change frames
- FN SWSetFrameTime(@brickSprite(x),-1)
- 'Move time <0 means we don't move sprite
- FN SWSetMoveTime(@brickSprite(x),-1)
- NEXT
-
- 'Put it together
- FOR x=0 TO 9
- err=FN SWAddSpriteToLayer(@brickLayer,@brickSprite(x))
- FN FatalError(err)
- NEXT
-
- err=FN SWAddLayerToWorld(@mySW,@brickLayer)
- FN FatalError(err)
-
- '--------------------------------------------------------------------
- 'Paddle Sprite, Frame, and Layer
- '--------------------------------------------------------------------
-
- 'Create paddle sprite
- movePtr&=LINE "PaddleMoveProc"
- err=FN SWSpriteFromPict(@paddleSprite,0,0,_paddleY,wndPort&+_portRect,_zTrue,2,2,-1,ttPtr&,movePtr&,_paddleRSRC)
- FN FatalError(err)
-
- 'Frame time <0 means we don't change frames
- FN SWSetFrameTime(@paddleSprite,-1)
-
- 'Create paddle frame from PICT resource
- err=FN SWFrameFromPict(@paddleFrame,_paddleRSRC)
- FN FatalError(err)
-
- 'Set collide proc
- collidePtr&=LINE "PaddleCollideProc"
- FN SWSetCollideProc(@paddleSprite,collidePtr&)
-
- 'Put it all together
- err=FN SWAddFrameToSprite(@paddleSprite,@paddleFrame)
- FN FatalError(err)
- err=FN SWAddSpriteToLayer(@paddleLayer,@paddleSprite)
- FN FatalError(err)
- err=FN SWAddLayerToWorld(@mySW,@paddleLayer)
- FN FatalError(err)
-
- '--------------------------------------------------------------------
- 'Final Set Up
- '--------------------------------------------------------------------
-
- 'Prepare loadframe for animation
- FN SWRefreshBackground(@mySW)
-
- CALL HIDECURSOR 'we're ready to go...
-
- 'Render first frame of animation
- FN SWAnimateSpriteWorld(@mySW)
-
- '--------------------------------------------------------------------
- 'Animation Loop
- '--------------------------------------------------------------------
-
- DO
- 'process normal sprite movement
- FN SWProcessSpriteWorld(@mySW)
- 'is game over?
- LONG IF gBallCounter=4
- BEEP:BEEP:BEEP
- GOTO "Finish Up"
- END IF
- 'check to see if ball collided with bricks
- FN SWCollideSpriteLayer(@ballLayer,@brickLayer)
- 'check to see if paddle collided with ball
- FN SWCollideSpriteLayer(@paddleLayer,@ballLayer)
- 'draw sprites on screen
- FN SWAnimateSpriteWorld(@mySW)
- CALL SYSTEMTASK
- UNTIL FN BUTTON
-
- '--------------------------------------------------------------------
- 'Dispose SpriteWorld & Exit
- '--------------------------------------------------------------------
- "Finish Up"
- err=FN SWDisposSpriteWorld(@mySW)
- FN FatalError(err)
-
- CALL INITCURSOR 'reset cursor
-
- END
-
-