home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 2000 November: Tool Chest / Dev.CD Nov 00 TC Disk 1.toast / Sample Code / Contributed / SpriteWorld / SpriteWorld Examples / Shark Attack / Sources & Headers / SpriteMoveProcs.c < prev    next >
Encoding:
C/C++ Source or Header  |  2000-10-06  |  13.6 KB  |  493 lines  |  [TEXT/CWIE]

  1. #include <SWIncludes.h>
  2. #include "Shark Attack.h"
  3. #include "NewSprite.h"
  4. #include "SpriteMoveProcs.h"
  5. #include "GlobalVariables.h"
  6. #include "SWSounds.h"
  7.  
  8.  
  9. //--------------------------------------------------------------------------------
  10. //   SubSpriteMoveProc
  11. //--------------------------------------------------------------------------------
  12.  
  13. SW_FUNC void SubSpriteMoveProc(SpritePtr subSpriteP)
  14. {
  15.     double            horizDelta, vertDelta;
  16.     short            bulletSpeed;
  17.     SpritePtr        newBulletSpriteP;
  18.     SubStructPtr    subStructP = (SubStructPtr)subSpriteP;
  19.     
  20.     horizDelta = subStructP->horizDelta;
  21.     vertDelta = subStructP->vertDelta;
  22.     
  23.     if (gKeys.left)                        // Increase speed if keys are down
  24.     {
  25.         if (subStructP->curDirection != kLeftDirection)
  26.         {
  27.             subStructP->curDirection = kLeftDirection;
  28.             SWSetCurrentFrameIndex(subSpriteP, kSubLeftFrameIndex);
  29.         }
  30.         
  31.         horizDelta -= kSubAcceleration;
  32.         if (horizDelta < -kSubMaxSpeed)
  33.             horizDelta = -kSubMaxSpeed;
  34.     }
  35.     else if (gKeys.right)
  36.     {
  37.         if (subStructP->curDirection != kRightDirection)
  38.         {
  39.             subStructP->curDirection = kRightDirection;
  40.             SWSetCurrentFrameIndex(subSpriteP, kSubRightFrameIndex);
  41.         }
  42.         
  43.         horizDelta += kSubAcceleration;
  44.         if (horizDelta > kSubMaxSpeed)
  45.             horizDelta = kSubMaxSpeed;
  46.     }
  47.     else                                // Decrease speed if no key is held
  48.     {
  49.         if (horizDelta > 0)
  50.         {
  51.             horizDelta -= kSubDeacceleration;
  52.             if (horizDelta < 0)
  53.                 horizDelta = 0;
  54.         }
  55.         else if (horizDelta < 0)
  56.         {
  57.             horizDelta += kSubDeacceleration;
  58.             if (horizDelta > 0)
  59.                 horizDelta = 0;
  60.         }
  61.     }
  62.     
  63.     
  64.     if (gKeys.up)                            // Increase speed if keys are down
  65.     {
  66.         vertDelta -= kSubAcceleration;
  67.         if (vertDelta < -kSubMaxSpeed)
  68.             vertDelta = -kSubMaxSpeed;
  69.     }
  70.     else if (gKeys.down)
  71.     {
  72.         vertDelta += kSubAcceleration;
  73.         if (vertDelta > kSubMaxSpeed)
  74.             vertDelta = kSubMaxSpeed;
  75.     }
  76.     else                                        // Decrease speed if no key is held
  77.     {
  78.         if (vertDelta > 0)
  79.         {
  80.             vertDelta -= kSubDeacceleration;
  81.             if (vertDelta < 0)
  82.                 vertDelta = 0;
  83.         }
  84.         else if (vertDelta < 0)
  85.         {
  86.             vertDelta += kSubDeacceleration;
  87.             if (vertDelta > 0)
  88.                 vertDelta = 0;
  89.         }
  90.     }
  91.  
  92.  
  93.     subStructP->horizDelta = horizDelta;
  94.     subStructP->vertDelta = vertDelta;
  95.  
  96.     subStructP->horizPos += subStructP->horizDelta;
  97.     subStructP->vertPos += subStructP->vertDelta;
  98.     
  99.     
  100.         // Keep within moveBounds
  101.     if (subStructP->vertPos < subSpriteP->moveBoundsRect.top)
  102.     {
  103.         subStructP->vertDelta = 0;
  104.         subStructP->vertPos = subSpriteP->moveBoundsRect.top;
  105.     }
  106.     else if (subStructP->vertPos + kSubHeight > subSpriteP->moveBoundsRect.bottom)
  107.     {
  108.         subStructP->vertDelta = 0;
  109.         subStructP->vertPos = subSpriteP->moveBoundsRect.bottom - kSubHeight;
  110.     }
  111.     
  112.     if (subStructP->horizPos < subSpriteP->moveBoundsRect.left)
  113.     {
  114.         subStructP->horizDelta = 0;
  115.         subStructP->horizPos = subSpriteP->moveBoundsRect.left;
  116.     }
  117.     else if (subStructP->horizPos + kSubWidth > subSpriteP->moveBoundsRect.right)
  118.     {
  119.         subStructP->horizDelta = 0;
  120.         subStructP->horizPos = subSpriteP->moveBoundsRect.right - kSubWidth;
  121.     }
  122.     
  123.     SWMoveSprite(subSpriteP, subStructP->horizPos, subStructP->vertPos);
  124.     
  125.     
  126.     if (gKeys.shoot || gKeys.shift)
  127.     {
  128.         if (subStructP->canShoot)
  129.         {
  130.             subStructP->canShoot = false;
  131.         
  132.             if ( (subStructP->numBulletsOnScreen < kMaxNumBullets) || kMachineGun)
  133.             {
  134.                 short    stereoPos;
  135.                 
  136.                 stereoPos = GetStereoPositionOfSprite(subSpriteP, &gSpriteWorldP->backRect);
  137.                 PlaySound2(kShootBulletSnd, 3, kReplaceSameSound, 128, stereoPos, k22khz, false);
  138.                 
  139.                 newBulletSpriteP = NewBulletSprite();
  140.                 ((BulletStructPtr)newBulletSpriteP)->parentStructP = subStructP;
  141.                 subStructP->numBulletsOnScreen++;
  142.                 gLastBulletP = newBulletSpriteP;
  143.                 
  144.                 if (kMachineGun)
  145.                     bulletSpeed = kMachineGunSpeed;
  146.                 else
  147.                     bulletSpeed = kNormalBulletSpeed;
  148.                 
  149.                 if (subStructP->curDirection == kLeftDirection)
  150.                 {
  151.                     newBulletSpriteP->horizMoveDelta = -bulletSpeed;
  152.                     newBulletSpriteP->horizMoveDelta += subStructP->horizDelta;
  153.                     SWSetSpriteLocation(newBulletSpriteP, 
  154.                         subSpriteP->destFrameRect.left - kBulletWidth, 
  155.                         subSpriteP->destFrameRect.top + 8);
  156.                 }
  157.                 else
  158.                 {
  159.                     newBulletSpriteP->horizMoveDelta = bulletSpeed;
  160.                     newBulletSpriteP->horizMoveDelta += subStructP->horizDelta;
  161.                     SWSetSpriteLocation(newBulletSpriteP, 
  162.                         subSpriteP->destFrameRect.right, 
  163.                         subSpriteP->destFrameRect.top + 8);
  164.                 }
  165.             }
  166.         }
  167.         else if (kMachineGun)
  168.         {
  169.             subStructP->nextShotDelay++;
  170.             if (subStructP->nextShotDelay >= kNextShotDelay)
  171.             {
  172.                 subStructP->nextShotDelay = 0;
  173.                 subStructP->canShoot = true;
  174.             }
  175.         }
  176.     }
  177.     else if (kMachineGun && subStructP->canShoot == false)
  178.     {
  179.         subStructP->nextShotDelay++;
  180.         if (subStructP->nextShotDelay >= kNextShotDelay)
  181.         {
  182.             subStructP->nextShotDelay = 0;
  183.             subStructP->canShoot = true;
  184.         }
  185.     }
  186.     else
  187.     {
  188.         subStructP->canShoot = true;
  189.     }
  190. }
  191.  
  192.  
  193. //--------------------------------------------------------------------------------
  194. //   LevelDoneSubMoveProc - installed when the level is done - slows sub to a stop
  195. //--------------------------------------------------------------------------------
  196.  
  197. SW_FUNC void LevelDoneSubMoveProc(SpritePtr subSpriteP)
  198. {
  199.     double            horizDelta, vertDelta;
  200.     SubStructPtr    subStructP = (SubStructPtr)subSpriteP;
  201.     
  202.     horizDelta = subStructP->horizDelta;
  203.     vertDelta = subStructP->vertDelta;
  204.     
  205.         // Slow the sub down if it's moving
  206.     if (horizDelta > 0)
  207.     {
  208.         horizDelta -= kSubDeacceleration;
  209.         if (horizDelta < 0)
  210.             horizDelta = 0;
  211.     }
  212.     else if (horizDelta < 0)
  213.     {
  214.         horizDelta += kSubDeacceleration;
  215.         if (horizDelta > 0)
  216.             horizDelta = 0;
  217.     }
  218.     
  219.     if (vertDelta > 0)
  220.     {
  221.         vertDelta -= kSubDeacceleration;
  222.         if (vertDelta < 0)
  223.             vertDelta = 0;
  224.     }
  225.     else if (vertDelta < 0)
  226.     {
  227.         vertDelta += kSubDeacceleration;
  228.         if (vertDelta > 0)
  229.             vertDelta = 0;
  230.     }
  231.  
  232.  
  233.     subStructP->horizDelta = horizDelta;
  234.     subStructP->vertDelta = vertDelta;
  235.  
  236.     subStructP->horizPos += subStructP->horizDelta;
  237.     subStructP->vertPos += subStructP->vertDelta;
  238.     
  239.     
  240.         // Keep within moveBounds
  241.     if (subStructP->vertPos < subSpriteP->moveBoundsRect.top)
  242.     {
  243.         subStructP->vertDelta = 0;
  244.         subStructP->vertPos = subSpriteP->moveBoundsRect.top;
  245.     }
  246.     else if (subStructP->vertPos + kSubHeight > subSpriteP->moveBoundsRect.bottom)
  247.     {
  248.         subStructP->vertDelta = 0;
  249.         subStructP->vertPos = subSpriteP->moveBoundsRect.bottom - kSubHeight;
  250.     }
  251.     
  252.     if (subStructP->horizPos < subSpriteP->moveBoundsRect.left)
  253.     {
  254.         subStructP->horizDelta = 0;
  255.         subStructP->horizPos = subSpriteP->moveBoundsRect.left;
  256.     }
  257.     else if (subStructP->horizPos + kSubWidth > subSpriteP->moveBoundsRect.right)
  258.     {
  259.         subStructP->horizDelta = 0;
  260.         subStructP->horizPos = subSpriteP->moveBoundsRect.right - kSubWidth;
  261.     }
  262.     
  263.     SWMoveSprite(subSpriteP, subStructP->horizPos, subStructP->vertPos);
  264. }
  265.  
  266.  
  267. //--------------------------------------------------------------------------------
  268. //   DeadSubSpriteMoveProc - installed as the sub's moveProc when the sub gets hit
  269. //--------------------------------------------------------------------------------
  270.  
  271. SW_FUNC void DeadSubSpriteMoveProc(SpritePtr subSpriteP)
  272. {
  273.     SubStructPtr subStructP = (SubStructPtr)subSpriteP;
  274.     
  275.     if (subSpriteP->oldFrameRect.top >= subSpriteP->moveBoundsRect.bottom)
  276.     {
  277.         gSubIsStillOnScreen = false;
  278.     }
  279.     else
  280.     {
  281.         subStructP->vertDelta += .05;
  282.         if (subStructP->vertDelta > 5)
  283.             subStructP->vertDelta = 5;
  284.         
  285.         subStructP->vertPos += subStructP->vertDelta;
  286.         
  287.         SWMoveSprite(subSpriteP, subStructP->horizPos, subStructP->vertPos);
  288.     }
  289. }
  290.  
  291.  
  292. ///--------------------------------------------------------------------------------------
  293. //  BulletSpriteMoveProc
  294. ///--------------------------------------------------------------------------------------
  295.  
  296. SW_FUNC void BulletSpriteMoveProc(SpritePtr srcSpriteP)
  297. {
  298.     SWOffsetSprite(srcSpriteP, srcSpriteP->horizMoveDelta, 0);
  299.     
  300.     if (srcSpriteP->oldFrameRect.right < srcSpriteP->moveBoundsRect.left ||
  301.         srcSpriteP->oldFrameRect.left > srcSpriteP->moveBoundsRect.right)
  302.     {
  303.         ((BulletStructPtr)srcSpriteP)->parentStructP->numBulletsOnScreen--;
  304.         SWRemoveSpriteFromAnimation(gSpriteWorldP, srcSpriteP, true);
  305.         if (srcSpriteP == gLastBulletP)
  306.             gLastBulletP = NULL;
  307.     }
  308.     
  309.         // Update the stereo position of the bullet sound based on the position
  310.         // of the bullet that was shot most recently.
  311.     if (srcSpriteP == gLastBulletP)
  312.     {
  313.         short    stereoPos, channelNum;
  314.         
  315.         channelNum = FindSound(kShootBulletSnd);
  316.         stereoPos = GetStereoPositionOfSprite(srcSpriteP, &gSpriteWorldP->backRect);
  317.         SetStereoPosition(channelNum, stereoPos);
  318.     }
  319. }
  320.  
  321.  
  322. ///--------------------------------------------------------------------------------------
  323. //  FishSpriteMoveProc
  324. ///--------------------------------------------------------------------------------------
  325.  
  326. SW_FUNC void FishSpriteMoveProc(SpritePtr fishSpriteP)
  327. {
  328.     FishStructPtr    fishStructP = (FishStructPtr)fishSpriteP;
  329.     
  330.         // If the fish was just hit and flashed white, change back to normal drawProc
  331.     if (fishStructP->hitCounter > 0)
  332.     {
  333.         if (--fishStructP->hitCounter == 0)
  334.         {
  335.             fishSpriteP->needsToBeDrawn = true;
  336.             SWSetSpriteDrawProc(fishSpriteP, gSpriteMaskDrawProc);
  337.         }
  338.     }
  339.     
  340.         // Don't move the fish if it was hit recently
  341.     if (fishStructP->moveDelay > 0)
  342.     {
  343.         fishStructP->moveDelay--;
  344.         return;
  345.     }
  346.     
  347.     SWOffsetSprite(fishSpriteP, fishSpriteP->horizMoveDelta, 0);
  348.     
  349.     if ( (fishSpriteP->oldFrameRect.right < fishSpriteP->moveBoundsRect.left &&
  350.          fishSpriteP->horizMoveDelta < 0) ||
  351.          (fishSpriteP->oldFrameRect.left > fishSpriteP->moveBoundsRect.right &&
  352.          fishSpriteP->horizMoveDelta > 0) )
  353.     {
  354.         gNumFishOnScreen--;
  355.         SWRemoveSpriteFromAnimation(gSpriteWorldP, fishSpriteP, true);
  356.     }
  357. }
  358.  
  359.  
  360. ///--------------------------------------------------------------------------------------
  361. //  SharkSpriteMoveProc
  362. ///--------------------------------------------------------------------------------------
  363.  
  364. SW_FUNC void SharkSpriteMoveProc(SpritePtr sharkSpriteP)
  365. {
  366.     SharkStructPtr    sharkStructP = (SharkStructPtr)sharkSpriteP;
  367.     SubStructPtr    subStructP = (SubStructPtr)gSubCloneP;
  368.     short            sharkMid = sharkSpriteP->oldFrameRect.top + kSharkHeight/2;
  369.     short            subMid = gSubCloneP->oldFrameRect.top + kSubHeight/2;
  370.     
  371.     
  372.         // If the fish was just hit and flashed white, change back to normal drawProc
  373.     if (sharkStructP->hitCounter > 0)
  374.     {
  375.         if (--sharkStructP->hitCounter == 0)
  376.         {
  377.             sharkSpriteP->needsToBeDrawn = true;
  378.             SWSetSpriteDrawProc(sharkSpriteP, gSpriteMaskDrawProc);
  379.         }
  380.     }
  381.     
  382.         // Make the shark follow the submarine
  383.     if (sharkMid > subMid)
  384.     {
  385.         sharkStructP->vertDelta -= kSharkAcceleration;
  386.         if (sharkStructP->vertDelta < -kSharkMaxSpeed)
  387.             sharkStructP->vertDelta = -kSharkMaxSpeed;
  388.         
  389.             // Make sure the shark didn't move past the sub
  390.         if (sharkMid + sharkStructP->vertDelta < subMid)
  391.         {
  392.             sharkStructP->vertDelta = subMid - sharkMid;
  393.         }
  394.     }
  395.     else if (sharkMid < subMid)
  396.     {
  397.         sharkStructP->vertDelta += kSharkAcceleration;
  398.         if (sharkStructP->vertDelta > kSharkMaxSpeed)
  399.             sharkStructP->vertDelta = kSharkMaxSpeed;
  400.         
  401.             // Make sure the shark didn't move past the sub
  402.         if (sharkMid + sharkStructP->vertDelta > subMid)
  403.         {
  404.             sharkStructP->vertDelta = subMid - sharkMid;
  405.         }
  406.     }
  407.     else if (subStructP->vertDelta == 0)
  408.     {
  409.         sharkStructP->vertDelta = 0;
  410.     }
  411.     
  412.         // Move the shark slower than normal if it was hit recently
  413.     if (sharkStructP->moveDelay > 0)
  414.     {
  415.         sharkStructP->moveDelay--;
  416.         sharkStructP->horizPos += sharkStructP->horizDelta/2;
  417.         sharkStructP->vertPos += sharkStructP->vertDelta/2;
  418.     }
  419.     else
  420.     {
  421.         sharkStructP->horizPos += sharkStructP->horizDelta;
  422.         sharkStructP->vertPos += sharkStructP->vertDelta;
  423.     }
  424.  
  425.  
  426.     SWMoveSprite(sharkSpriteP, sharkStructP->horizPos, sharkStructP->vertPos);
  427.     
  428.         // Turn the shark around if it went past the edge of the screen
  429.     if ( (sharkSpriteP->oldFrameRect.right < sharkSpriteP->moveBoundsRect.left-40 &&
  430.          sharkStructP->horizDelta < 0) ||
  431.          (sharkSpriteP->oldFrameRect.left > sharkSpriteP->moveBoundsRect.right+40 &&
  432.          sharkStructP->horizDelta > 0) )
  433.     {
  434.         sharkStructP->horizDelta = -sharkStructP->horizDelta;
  435.         
  436.             // Change set of frames used to animate the shark
  437.         if (sharkStructP->horizDelta > 0)
  438.         {
  439.             SWSetSpriteFrameRange(sharkSpriteP, 0, 2);
  440.             SWSetCurrentFrameIndex(sharkSpriteP, 0);
  441.         }
  442.         else
  443.         {
  444.             SWSetSpriteFrameRange(sharkSpriteP, 3, 5);
  445.             SWSetCurrentFrameIndex(sharkSpriteP, 3);
  446.         }
  447.     }
  448. }
  449.  
  450.  
  451. ///--------------------------------------------------------------------------------------
  452. //    FishHitDrawProc - Note: this DrawProc requires the sprite to have a maskRgn. If you
  453. //    look at NewSprite(), you'll see that the fish and shark sprites were both loaded 
  454. //    with kFatMask, instead of kPixelMask, so this drawProc could be used for them.
  455. //
  456. //    Note also that since PaintRgn gives us no option to clip our drawing to the dstRect,
  457. //    we turn the dstRect into a region and "clip" the frame's region to the dstRect
  458. //    region with SectRgn. An alternative would be to call ClipRect to set the current
  459. //    clipping region to dstRect before making the call to PaintRgn. (Remembering to 
  460. //    restore the old clipping region when done). This clipping must be done because
  461. //    sometimes (especially in scrolling games) only part of a sprite will be drawn.
  462. ///--------------------------------------------------------------------------------------
  463.  
  464. SW_FUNC void FishHitDrawProc(
  465.     FramePtr srcFrameP,
  466.     FramePtr dstFrameP,
  467.     Rect* srcRect,
  468.     Rect* dstRect)
  469. {
  470.     #pragma        unused(dstFrameP)    // Tell CodeWarrior this variable is unused
  471.     
  472.     if (srcFrameP->maskRgn != NULL)
  473.     {
  474.         Rect rgnRect = (**srcFrameP->maskRgn).rgnBBox;
  475.  
  476.             // move the mask region to the sprite location
  477.         OffsetRgn(srcFrameP->maskRgn,
  478.             (dstRect->left - (srcRect->left - srcFrameP->frameRect.left) - rgnRect.left) 
  479.             + srcFrameP->offsetPoint.h,
  480.             (dstRect->top - (srcRect->top - srcFrameP->frameRect.top) - rgnRect.top)
  481.             + srcFrameP->offsetPoint.v);
  482.         
  483.             // Here we "clip" the srcFrameP->maskRgn with the dstRect.
  484.         RectRgn(gTempRgn, dstRect);
  485.         SectRgn(gTempRgn, srcFrameP->maskRgn, gTempRgn);
  486.         
  487.         ForeColor(whiteColor);
  488.         PaintRgn(gTempRgn);
  489.         ForeColor(blackColor);
  490.     }
  491. }
  492.  
  493.