home *** CD-ROM | disk | FTP | other *** search
- ///--------------------------------------------------------------------------------------
- // SimpleBreakOut.c
- //
- // Portions are Copyright © 1993 Tony Myles, All rights reserved worldwide.
- //
- // Description: This is a very basic breakout type game that demonstrates
- // SpriteWorld's efficient handling of inactive sprites.
- ///--------------------------------------------------------------------------------------
-
-
- #include <SWIncludes.h> // Automatically include all SpriteWorld.h files
- #include <SWGameUtils.h>
-
- #include "SWApplication.h"
- #include "SimpleBreakOut.h"
-
-
-
- #define kMaxFPS 0 // Set to 0 for maximum speed
- #define kSyncToVBL true // Sync animation to VBL?
-
-
- enum
- {
- kBallHorizDelta = 5,
- kBallVertDelta = 5,
- kNumberOfBrickColumns = 10,
- kNumberOfBrickRows = 5,
- kTotalNumberOfBricks = (kNumberOfBrickColumns * kNumberOfBrickRows),
- kBrickCIconID = 129,
- kBreakBallCIconID = 130,
- kPaddleCIconID = 131
- };
-
-
-
- Point oldPoint, newPoint; // Mouse variables used for moving paddle
- short gBrickNum;
-
-
- ///--------------------------------------------------------------------------------------
- // main
- ///--------------------------------------------------------------------------------------
-
- void main(void)
- {
- WindowPtr myWindowP = NULL;
- Rect windRect;
-
-
- Initialize(kNumberOfMoreMastersCalls);
-
- if (!SWHasSystem7())
- CantRunOnThisMachine();
-
-
- // Create and set up the window
- myWindowP = GetNewCWindow(kWindowResID, NULL, (WindowPtr)-1L);
-
- if (myWindowP != NULL)
- {
- // Center window in screen
- windRect = myWindowP->portRect;
- CenterRect(&windRect, &qd.screenBits.bounds);
- MoveWindow(myWindowP, windRect.left, windRect.top, false);
-
- ShowWindow(myWindowP);
- SetPort(myWindowP);
- }
- else
- CantFindResource();
-
-
- PerformSimpleAnimation((CWindowPtr)myWindowP);
- }
-
-
- ///--------------------------------------------------------------------------------------
- // PerformSimpleAnimation
- ///--------------------------------------------------------------------------------------
-
- void PerformSimpleAnimation(CWindowPtr srcWindowP)
- {
- OSErr err;
- PixPatHandle pixPatH;
-
- SpriteWorldPtr spriteWorldP;
- SpriteLayerPtr brickLayerP;
- SpriteLayerPtr ballLayerP;
- SpriteLayerPtr paddleLayerP;
- SpritePtr brickSpriteArray[kTotalNumberOfBricks];
- SpritePtr ballSpriteP;
- SpritePtr paddleSpriteP;
-
- short horizOffset, vertOffset, brickHoriz, brickVert, col, row, n;
- Rect moveBoundsRect;
-
-
- SetPort((GrafPtr)srcWindowP);
- SetCursor(*GetCursor(watchCursor));
-
-
- //
- // STEP #1: initialize the sprite world package
- //
-
- err = SWEnterSpriteWorld();
- FatalError(err);
-
-
- //
- // STEP #2: create the various pieces that we need
- //
-
- // create the sprite world
- err = SWCreateSpriteWorldFromWindow(&spriteWorldP, srcWindowP, NULL, NULL, 0);
- FatalError(err);
-
- // create the brick layer
- err = SWCreateSpriteLayer(&brickLayerP);
- FatalError(err);
-
- // create the ball layer
- err = SWCreateSpriteLayer(&ballLayerP);
- FatalError(err);
-
- // create the paddle layer
- err = SWCreateSpriteLayer(&paddleLayerP);
- FatalError(err);
-
- // Create the first brick sprite
- err = SWCreateSpriteFromCicnResource(spriteWorldP, &(brickSpriteArray[0]), NULL,
- kBrickCIconID, 1, kNoMask);
-
- // Clone the other brick sprites off the first one
- for (gBrickNum = 1; gBrickNum < kTotalNumberOfBricks; gBrickNum++)
- {
- err = SWCloneSprite(brickSpriteArray[0], &brickSpriteArray[gBrickNum], NULL);
- FatalError(err);
- }
-
- // create ball sprite
- err = SWCreateSpriteFromCicnResource(spriteWorldP, &ballSpriteP, NULL,
- kBreakBallCIconID, 1, kFatMask);
- FatalError(err);
-
- // create paddle sprite
- err = SWCreateSpriteFromCicnResource(spriteWorldP, &paddleSpriteP, NULL,
- kPaddleCIconID, 1, kFatMask);
- FatalError(err);
-
-
-
- //
- // STEP #3: put the pieces together (must be done BEFORE the sprite world is locked!)
- //
-
- for (gBrickNum = 0; gBrickNum < kTotalNumberOfBricks; gBrickNum++)
- {
- // add the brick sprite to the brick layer
- SWAddSprite(brickLayerP, brickSpriteArray[gBrickNum]);
- }
-
- // add the ball sprite to the ball layer
- SWAddSprite(ballLayerP, ballSpriteP);
-
- // add the paddle sprite to the paddle layer
- SWAddSprite(paddleLayerP, paddleSpriteP);
-
- // add the layers to the world
- SWAddSpriteLayer(spriteWorldP, brickLayerP);
- SWAddSpriteLayer(spriteWorldP, ballLayerP);
- SWAddSpriteLayer(spriteWorldP, paddleLayerP);
-
-
-
- //
- // STEP #4: set things up for the animation
- // (can be done before or after locking the SpriteWorld)
- //
-
- // calculate the movement boundary rectangle
- moveBoundsRect = srcWindowP->portRect;
-
- horizOffset = (brickSpriteArray[0]->curFrameP->frameRect.right - brickSpriteArray[0]->curFrameP->frameRect.left) + 2;
- vertOffset = (brickSpriteArray[0]->curFrameP->frameRect.bottom - brickSpriteArray[0]->curFrameP->frameRect.top) + 2;
- brickHoriz = 2;
- brickVert = (vertOffset * 2);
- gBrickNum = 0;
-
- // set up the bricks
- for (col = 0; col < kNumberOfBrickColumns; col++)
- {
- brickVert = (vertOffset * 2);
-
- for (row = 0; row < kNumberOfBrickRows; row++)
- {
- // set the sprite’s initial location
- SWSetSpriteLocation(brickSpriteArray[gBrickNum], brickHoriz, brickVert);
- SWSetSpriteMoveTime(brickSpriteArray[gBrickNum], -1);
-
- gBrickNum++;
- brickVert += vertOffset;
- }
-
- brickHoriz += horizOffset;
- }
-
- // set the ball’s movement characteristics
- SWSetSpriteLocation(ballSpriteP, - 100, 50);
- SWSetSpriteMoveBounds(ballSpriteP, &moveBoundsRect);
- SWSetSpriteMoveDelta(ballSpriteP, kBallHorizDelta, kBallVertDelta);
- SWSetSpriteMoveProc(ballSpriteP, BallMoveProc);
- SWSetSpriteCollideProc(ballSpriteP, BallCollideProc);
-
- // set the paddle’s movement characteristics
- SWSetSpriteMoveBounds(paddleSpriteP, &moveBoundsRect);
- SetUpPaddle(paddleSpriteP);
- SWSetSpriteMoveProc(paddleSpriteP, PaddleMoveProc);
- SWSetSpriteCollideProc(paddleSpriteP, PaddleCollideProc);
-
-
- //
- // Set the DrawProcs to BlitPixie
- //
-
- // Set the sprite drawProcs
- if (spriteWorldP->pixelDepth == 8) // 256 colors
- {
- SWSetSpriteDrawProc(ballSpriteP, BlitPixie8BitMaskDrawProc);
- SWSetSpriteDrawProc(paddleSpriteP, BlitPixie8BitRectDrawProc);
- }
- else if ( !(SW_PPC && spriteWorldP->pixelDepth < 8) ) // Not 256 colors
- {
- SWSetSpriteDrawProc(ballSpriteP, BlitPixieAllBitMaskDrawProc);
- SWSetSpriteDrawProc(paddleSpriteP, BlitPixieAllBitRectDrawProc);
- }
-
- // Set the screen drawProcs
- if (spriteWorldP->pixelDepth == 8) // 256 colors
- {
- SWSetSpriteWorldScreenDrawProc(spriteWorldP, BlitPixie8BitRectDrawProc);
- SWSetSpriteWorldOffscreenDrawProc(spriteWorldP, BlitPixie8BitRectDrawProc);
- }
- else if ( !(SW_PPC && spriteWorldP->pixelDepth < 8) ) // Not 256 colors
- {
- SWSetSpriteWorldScreenDrawProc(spriteWorldP, BlitPixieAllBitRectDrawProc);
- SWSetSpriteWorldOffscreenDrawProc(spriteWorldP, BlitPixieAllBitRectDrawProc);
- }
-
-
-
- //
- // STEP #5: lock the sprite world !!! VERY IMPORTANT !!!
- //
-
- SWLockSpriteWorld(spriteWorldP);
-
-
- HideCursor();
-
-
- //
- // SETP #6: Draw a nice background. Must be done *after* locking the SpriteWorld!
- //
-
- SWSetPortToBackground(spriteWorldP);
-
- if (spriteWorldP->pixelDepth == 1)
- pixPatH = GetPixPat(129); // B&W dithered background
- else
- pixPatH = GetPixPat(128); // Color
-
- if (pixPatH != NULL)
- {
- FillCRect(&moveBoundsRect, pixPatH);
- DisposePixPat(pixPatH);
- }
-
-
- SWSetPortToWindow(spriteWorldP);
-
-
- //
- // STEP #7: update the SpriteWorld and run the animation
- //
-
-
- SetCursor(&qd.arrow);
- SWUpdateSpriteWorld(spriteWorldP, true);
- SWSetSpriteWorldMaxFPS( spriteWorldP, kMaxFPS );
- SWSyncSpriteWorldToVBL(spriteWorldP, kSyncToVBL);
- SWSetCleanUpSpriteWorld(spriteWorldP);
-
- FatalError( SWStickyError() ); // Make sure no errors got past us during setup
-
- while (!Button())
- {
- SWProcessSpriteWorld(spriteWorldP);
-
- // did we lose the last ball?
- if (ballSpriteP->userData == 4)
- {
- SysBeep(1);
- break;
- }
- else if (gBrickNum == 0)
- {
- for (n=0; n<3; n++)
- SysBeep(1);
- break;
- }
-
- // see if the ball has hit the paddle
- SWCollideSpriteLayer(spriteWorldP, paddleLayerP, ballLayerP);
-
- // see if the ball has hit the bricks
- SWCollideSpriteLayer(spriteWorldP, ballLayerP, brickLayerP);
-
- // Make sure no errors occurred during a MoveProc, etc.
- FatalError( SWStickyError() );
-
- SWAnimateSpriteWorld(spriteWorldP);
- }
-
-
- //
- // STEP #8: Clean up
- //
-
- SWUnlockSpriteWorld(spriteWorldP);
- SWDisposeSpriteWorld(&spriteWorldP);
- SWExitSpriteWorld();
-
- FlushEvents(everyEvent, 0);
- ShowCursor();
- }
-
-
- ///--------------------------------------------------------------------------------------
- // BallCollideProc
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC void BallCollideProc(SpritePtr ballSpriteP, SpritePtr brickSpriteP, Rect* sectRect)
- {
- short offset;
- short vertMoveDelta = ballSpriteP->vertMoveDelta;
- short horizMoveDelta = ballSpriteP->horizMoveDelta;
-
-
- if (vertMoveDelta < 0)
- vertMoveDelta = -vertMoveDelta;
-
- if (horizMoveDelta < 0)
- horizMoveDelta = -horizMoveDelta;
-
- if (brickSpriteP->isVisible)
- {
- SWSetSpriteVisible(brickSpriteP, false);
- gBrickNum--;
-
-
-
- if (vertMoveDelta < sectRect->bottom - sectRect->top)
- {
- // Hit left or right side of brick
-
- // Reverse direction
- ballSpriteP->horizMoveDelta = -ballSpriteP->horizMoveDelta;
-
- // "Bounce" ball off bricks
- offset = (sectRect->right - sectRect->left) * 2;
- if (ballSpriteP->horizMoveDelta < 0)
- offset = -offset;
-
- SWOffsetSprite(ballSpriteP, offset, 0);
- }
- else if (horizMoveDelta < sectRect->right - sectRect->left)
- {
- // Hit top or bottom of brick
-
- // Reverse direction
- ballSpriteP->vertMoveDelta = -ballSpriteP->vertMoveDelta;
-
- // "Bounce" ball off bricks
- offset = (sectRect->bottom - sectRect->top) * 2;
- if (ballSpriteP->vertMoveDelta < 0)
- offset = -offset;
-
- SWOffsetSprite(ballSpriteP, 0, offset);
- }
- else
- {
- // Hit corner of brick
-
- if ((sectRect->right - sectRect->left) > (sectRect->bottom - sectRect->top) )
- {
- // Hit left or right side of brick
-
- // Reverse direction
- ballSpriteP->horizMoveDelta = -ballSpriteP->horizMoveDelta;
-
- // "Bounce" ball off bricks
- offset = (sectRect->right - sectRect->left) * 2;
- if (ballSpriteP->horizMoveDelta < 0)
- offset = -offset;
-
- SWOffsetSprite(ballSpriteP, offset, 0);
- }
- else
- {
- // Hit top or bottom of brick
-
- // Reverse direction
- ballSpriteP->vertMoveDelta = -ballSpriteP->vertMoveDelta;
-
- // "Bounce" ball off bricks
- offset = (sectRect->bottom - sectRect->top) * 2;
- if (ballSpriteP->vertMoveDelta < 0)
- offset = -offset;
-
- SWOffsetSprite(ballSpriteP, 0, offset);
- }
- }
- }
- }
-
-
- ///--------------------------------------------------------------------------------------
- // PaddleCollideProc
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC void PaddleCollideProc(SpritePtr paddleSpriteP, SpritePtr ballSpriteP, Rect* sectRect)
- {
- short paddleMid = (paddleSpriteP->destFrameRect.right -
- paddleSpriteP->destFrameRect.left)/2;
- short ballMid = (ballSpriteP->destFrameRect.right -
- ballSpriteP->destFrameRect.left)/2;
-
- if ( (ballSpriteP->destFrameRect.bottom - ballSpriteP->vertMoveDelta)
- > paddleSpriteP->destFrameRect.bottom )
- return; // Return if ball did not hit above bottom of paddle
-
-
- // Set ball direction according to position hit on paddle
- if (ballSpriteP->destFrameRect.left + ballMid >
- paddleSpriteP->destFrameRect.left + paddleMid)
- {
- ballSpriteP->horizMoveDelta = ( (ballSpriteP->destFrameRect.left + ballMid) -
- (paddleSpriteP->destFrameRect.left + paddleMid) )/4;
-
- if (ballSpriteP->horizMoveDelta > 0)
- ballSpriteP->vertMoveDelta = kBallVertDelta - ballSpriteP->horizMoveDelta/2;
- else
- ballSpriteP->vertMoveDelta = kBallVertDelta + ballSpriteP->horizMoveDelta/2;
-
- if (ballSpriteP->horizMoveDelta == 0)
- ballSpriteP->horizMoveDelta++;
- }
- else
- {
- ballSpriteP->horizMoveDelta = ( (ballSpriteP->destFrameRect.left + ballMid) -
- (paddleSpriteP->destFrameRect.left + paddleMid) )/4;
-
- if (ballSpriteP->horizMoveDelta > 0)
- ballSpriteP->vertMoveDelta = kBallVertDelta - ballSpriteP->horizMoveDelta/2;
- else
- ballSpriteP->vertMoveDelta = kBallVertDelta + ballSpriteP->horizMoveDelta/2;
-
- if (ballSpriteP->horizMoveDelta == 0)
- ballSpriteP->horizMoveDelta--;
- }
-
-
- // If ball was moving down, turn it around
- if (ballSpriteP->vertMoveDelta > 0)
- ballSpriteP->vertMoveDelta = -ballSpriteP->vertMoveDelta;
-
- if ( (ballSpriteP->destFrameRect.bottom - ballSpriteP->vertMoveDelta)
- > paddleSpriteP->destFrameRect.top )
- {
- SWOffsetSprite(ballSpriteP, 0, sectRect->top - sectRect->bottom);
- }
-
- }
-
-
- ///--------------------------------------------------------------------------------------
- // SetUpPaddle
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC void SetUpPaddle(SpritePtr paddleSpriteP)
- {
- short middle = (paddleSpriteP->moveBoundsRect.right -
- paddleSpriteP->moveBoundsRect.left) / 2;
- short paddleWidth = (paddleSpriteP->destFrameRect.right -
- paddleSpriteP->destFrameRect.left);
- Point globalPoint;
-
-
- GetMouse(&newPoint);
- globalPoint = newPoint;
- LocalToGlobal(&globalPoint);
-
- if (globalPoint.h < middle)
- {
- SWSetSpriteLocation(paddleSpriteP, paddleSpriteP->moveBoundsRect.left +
- globalPoint.h, paddleSpriteP->moveBoundsRect.bottom - 30);
- }
- else if (qd.screenBits.bounds.right - globalPoint.h < middle)
- {
- SWSetSpriteLocation(paddleSpriteP, paddleSpriteP->moveBoundsRect.right+1 -
- (qd.screenBits.bounds.right - globalPoint.h) - paddleWidth,
- paddleSpriteP->moveBoundsRect.bottom - 30);
- }
- else
- {
- SWSetSpriteLocation(paddleSpriteP, paddleSpriteP->moveBoundsRect.left +
- middle - paddleWidth/2, paddleSpriteP->moveBoundsRect.bottom - 30);
- }
- }
-
-
- ///--------------------------------------------------------------------------------------
- // PaddleMoveProc
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC void PaddleMoveProc(SpritePtr paddleSpriteP)
- {
- oldPoint = newPoint;
- GetMouse(&newPoint);
-
- SWOffsetSprite(paddleSpriteP, newPoint.h - oldPoint.h, 0);
-
- if (paddleSpriteP->destFrameRect.left < paddleSpriteP->moveBoundsRect.left)
- {
- SWOffsetSprite(paddleSpriteP, (paddleSpriteP->moveBoundsRect.left -
- paddleSpriteP->destFrameRect.left) , 0);
- }
- else if (paddleSpriteP->destFrameRect.right > paddleSpriteP->moveBoundsRect.right)
- {
- SWOffsetSprite(paddleSpriteP, (paddleSpriteP->moveBoundsRect.right -
- paddleSpriteP->destFrameRect.right) , 0);
- }
- }
-
-
- ///--------------------------------------------------------------------------------------
- // BallMoveProc
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC void BallMoveProc(SpritePtr srcSpriteP)
- {
- register short inset;
-
-
- // Move the sprite
- SWOffsetSprite(srcSpriteP, srcSpriteP->horizMoveDelta, srcSpriteP->vertMoveDelta);
-
-
- // Check for collision with walls
- if ((srcSpriteP->destFrameRect.left < srcSpriteP->moveBoundsRect.left) &&
- (srcSpriteP->horizMoveDelta < 0)) // Past left bounds and moving left
- {
- srcSpriteP->horizMoveDelta *= -1; // Reverse direction
- inset = srcSpriteP->moveBoundsRect.left - srcSpriteP->destFrameRect.left;
- SWOffsetSprite( srcSpriteP, inset * 2, 0 ); // "Bounce" sprite off bounds
-
- }
- else if ((srcSpriteP->destFrameRect.right > srcSpriteP->moveBoundsRect.right)&&
- (srcSpriteP->horizMoveDelta > 0)) // Past right bounds and moving right
- {
- srcSpriteP->horizMoveDelta *= -1; // Reverse direction
- inset = srcSpriteP->moveBoundsRect.right - srcSpriteP->destFrameRect.right;
- SWOffsetSprite( srcSpriteP, inset * 2, 0 ); // "Bounce" sprite off bounds
- }
-
- if ((srcSpriteP->destFrameRect.top < srcSpriteP->moveBoundsRect.top) &&
- (srcSpriteP->vertMoveDelta < 0)) // Past top bounds and moving up
- {
- srcSpriteP->vertMoveDelta *= -1; // Reverse direction
- inset = srcSpriteP->moveBoundsRect.top - srcSpriteP->destFrameRect.top;
- SWOffsetSprite( srcSpriteP, 0, inset * 2 ); // "Bounce" sprite off bounds
- }
- else if ((srcSpriteP->oldFrameRect.top > srcSpriteP->moveBoundsRect.bottom)&&
- (srcSpriteP->vertMoveDelta > 0)) // Past bottom bounds and moving down
- {
- SysBeep(1);
- srcSpriteP->userData++;
-
- SWSetSpriteLocation(srcSpriteP, -100, 50);
-
- SWSetSpriteMoveDelta(srcSpriteP, kBallHorizDelta, kBallVertDelta);
- }
- }
-