home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Mac Game Programming Gurus / TricksOfTheMacGameProgrammingGurus.iso / More Source / Pascal / Book Demos in Pascal / SpriteEngine / SE Balls / SpriteHandlers.p < prev    next >
Encoding:
Text File  |  1995-04-04  |  5.0 KB  |  170 lines  |  [TEXT/MWPS]

  1. unit SpriteHandlers;
  2.  
  3. interface
  4.  
  5.     uses
  6. {$IFC UNDEFINED THINK_PASCAL}
  7.         Types, QuickDraw, Fonts, Events, Packages, Menus, Dialogs, Windows,{}
  8.         OSUtils, ToolUtils, OSEvents, 
  9. {$ENDC}
  10.         QDOffScreen, SpriteStructure, SpriteTools;
  11.  
  12.     procedure MoveSprite (theSprite: SpritePtr);
  13.     procedure HitSprite (theSprite: SpritePtr; anotherSprite: SpritePtr);
  14.     procedure InitSprites;
  15.  
  16. implementation
  17.  
  18. { Custom handlers - application dependent ***}
  19. {}
  20. {Edit this as necessary. It should always include the following three routines:}
  21. {}
  22. {MoveSprite: move the sprite}
  23. {}
  24. {HitSprite: handle collisions between two sprites}
  25. {}
  26. {InitSprites: Load all faces and create initial sprites }
  27.  
  28.  
  29. var firstFace, secondFace, thirdFace:GrafPtr;
  30.  
  31.  
  32. (* SeparateBalls is explicitly written to separate two balls with
  33. diameter 32. *)
  34.  
  35. const
  36. kBallDiameterSquared= 33*33;
  37.  
  38. Procedure SeparateBalls(theSprite:SpritePtr; anotherSprite:SpritePtr);
  39.  
  40.     var initVector, nowVector:Point;
  41.     absH, absV:Integer;
  42.     moveH, moveV:Integer;
  43.     frac:Integer;
  44.  
  45. function Sgn(i:Integer):Integer;
  46. begin
  47.     if i > 0 then Sgn := 1
  48.     else
  49.     if i < 0 then Sgn := -1
  50.     else
  51.     Sgn := 0;
  52. end; {Sgn}
  53.  
  54. (*Separate*)
  55.      begin 
  56. frac := 0;
  57.     initVector.h := theSprite^.position.h - anotherSprite^.position.h;
  58.     initVector.v := theSprite^.position.v - anotherSprite^.position.v;
  59.     absH := abs(initVector.h);
  60.     absV := abs(initVector.v);
  61.     moveH := Sgn(initVector.h);
  62.     moveV := Sgn(initVector.v);
  63.     If  moveH = 0 Then
  64.         If moveV = 0 Then
  65.             moveV := 1;
  66.     Repeat
  67.         If absH > absV Then
  68.              begin 
  69.             theSprite^.position.h := theSprite^.position.h + moveH;
  70.             anotherSprite^.position.h := anotherSprite^.position.h - moveH;
  71.             frac := frac + absV;
  72.             If  frac > absH Then
  73.                  begin 
  74.                 theSprite^.position.v := theSprite^.position.v + moveV;
  75.                 anotherSprite^.position.v := anotherSprite^.position.v - moveV;
  76.                 frac := frac - absH;
  77.              End;
  78.          End
  79.         Else         
  80.          begin 
  81.             theSprite^.position.v := theSprite^.position.v + moveV;
  82.             anotherSprite^.position.v := anotherSprite^.position.v - moveV;
  83.             frac := frac + absH;
  84.             If  frac > absV Then
  85.             begin 
  86.                 theSprite^.position.h := theSprite^.position.h + moveH;
  87.                 anotherSprite^.position.h := anotherSprite^.position.h - moveH;
  88.                 frac := frac - absV;
  89.              End;
  90.          End;
  91.  
  92.         nowVector.h := theSprite^.position.h - anotherSprite^.position.h;
  93.         nowVector.v := theSprite^.position.v - anotherSprite^.position.v;
  94.      Until LongInt(nowVector.h) * nowVector.h + LongInt(nowVector.v) * nowVector.v > kBallDiameterSquared;
  95.  End; (*SeparateBalls*)
  96.  
  97.  
  98.  
  99. Procedure MoveSprite(theSprite:SpritePtr);
  100. begin 
  101.     theSprite^.speed.v := theSprite^.speed.v + 1; { Simple gravity}
  102.     theSprite^.fixedPointPosition.h := theSprite^.fixedPointPosition.h + theSprite^.speed.h;
  103.     theSprite^.fixedPointPosition.v := theSprite^.fixedPointPosition.v + theSprite^.speed.v;
  104.     theSprite^.position.h := BSR(theSprite^.fixedPointPosition.h, 4);
  105.     theSprite^.position.v := BSR(theSprite^.fixedPointPosition.v, 4);
  106.     if KeepOnScreenFixed(theSprite) then ;
  107. End; (*MoveSprite*)
  108.  
  109.  
  110. Procedure HitSprite(theSprite:SpritePtr; anotherSprite:SpritePtr);
  111. var perpendicularHelpLine, parallelHelpLine, p1, p2, n1, n2:Point;
  112. begin
  113. {Check for a *real* collision!}
  114.     If RegionHit(theSprite, anotherSprite) Then
  115.          begin 
  116.         perpendicularHelpLine.h := theSprite^.position.h - anotherSprite^.position.h;
  117.         perpendicularHelpLine.v := theSprite^.position.v - anotherSprite^.position.v;
  118.         parallelHelpLine.h := perpendicularHelpLine.v;
  119.         parallelHelpLine.v := -perpendicularHelpLine.h;
  120. {Move them away from each other}
  121.         SeparateBalls(theSprite, anotherSprite);
  122. {Make the fixed-point positions follow!}
  123.         theSprite^.fixedPointPosition.h := BSL(theSprite^.position.h, 4);
  124.         theSprite^.fixedPointPosition.v := BSL(theSprite^.position.v, 4);
  125.         anotherSprite^.fixedPointPosition.h := BSL(anotherSprite^.position.h, 4);
  126.         anotherSprite^.fixedPointPosition.v := BSL(anotherSprite^.position.v, 4);
  127.  
  128. {Swap the speed components that are parallell to parallelHelpLine}
  129.         SplitVector(theSprite^.speed, parallelHelpLine, p1, n1);
  130.         SplitVector(anotherSprite^.speed, parallelHelpLine, p2, n2);
  131.  
  132.         anotherSprite^.speed.h := p2.h + n1.h;
  133.         anotherSprite^.speed.v := p2.v + n1.v;
  134.  
  135.         theSprite^.speed.h := p1.h + n2.h;
  136.         theSprite^.speed.v := p1.v + n2.v;
  137.      End; { if RegionHit}
  138.  End; (*HitSprite*)
  139.  
  140.  
  141. Procedure InitSprites;
  142.  
  143.     var theSprite:SpritePtr;
  144.  
  145. (*Load all pictures*)
  146.      begin 
  147. firstFace := LoadFaceFromCicn(128);            (*cicn resource #128.*)
  148.     secondFace := LoadFaceFromCicn(129);            (*cicn resource #129.*)
  149.     thirdFace := LoadFaceFromCicn(130);            (*cicn resource #130.*)
  150.  
  151. (*Create sprites*)
  152.     theSprite := NewSprite;
  153.     theSprite^.face := firstFace;
  154.     SetPt(theSprite^.fixedPointPosition, BSL(100 , 4), BSL(100 , 4));
  155.     SetPt(theSprite^.speed, 1, 16);
  156.  
  157.     theSprite := NewSprite;
  158.     theSprite^.face := secondFace;
  159.     SetPt(theSprite^.fixedPointPosition, BSL(50 , 4), BSL(50 , 4));
  160.     SetPt(theSprite^.speed, 16, 1);
  161.  
  162.     theSprite := NewSprite;
  163.     theSprite^.face := thirdFace;
  164.     SetPt(theSprite^.fixedPointPosition, BSL(150 , 4), BSL(150 , 4));
  165.     SetPt(theSprite^.speed, Rand(7)-3, Rand(7)-3);
  166.  End; (*InitSprites*)
  167.  
  168.  end.
  169.  
  170.