home *** CD-ROM | disk | FTP | other *** search
Text File | 1995-04-04 | 5.0 KB | 170 lines | [TEXT/MWPS] |
- unit SpriteHandlers;
-
- interface
-
- uses
- {$IFC UNDEFINED THINK_PASCAL}
- Types, QuickDraw, Fonts, Events, Packages, Menus, Dialogs, Windows,{}
- OSUtils, ToolUtils, OSEvents,
- {$ENDC}
- QDOffScreen, SpriteStructure, SpriteTools;
-
- procedure MoveSprite (theSprite: SpritePtr);
- procedure HitSprite (theSprite: SpritePtr; anotherSprite: SpritePtr);
- procedure InitSprites;
-
- implementation
-
- { Custom handlers - application dependent ***}
- {}
- {Edit this as necessary. It should always include the following three routines:}
- {}
- {MoveSprite: move the sprite}
- {}
- {HitSprite: handle collisions between two sprites}
- {}
- {InitSprites: Load all faces and create initial sprites }
-
-
- var firstFace, secondFace, thirdFace:GrafPtr;
-
-
- (* SeparateBalls is explicitly written to separate two balls with
- diameter 32. *)
-
- const
- kBallDiameterSquared= 33*33;
-
- Procedure SeparateBalls(theSprite:SpritePtr; anotherSprite:SpritePtr);
-
- var initVector, nowVector:Point;
- absH, absV:Integer;
- moveH, moveV:Integer;
- frac:Integer;
-
- function Sgn(i:Integer):Integer;
- begin
- if i > 0 then Sgn := 1
- else
- if i < 0 then Sgn := -1
- else
- Sgn := 0;
- end; {Sgn}
-
- (*Separate*)
- begin
- frac := 0;
- initVector.h := theSprite^.position.h - anotherSprite^.position.h;
- initVector.v := theSprite^.position.v - anotherSprite^.position.v;
- absH := abs(initVector.h);
- absV := abs(initVector.v);
- moveH := Sgn(initVector.h);
- moveV := Sgn(initVector.v);
- If moveH = 0 Then
- If moveV = 0 Then
- moveV := 1;
- Repeat
- If absH > absV Then
- begin
- theSprite^.position.h := theSprite^.position.h + moveH;
- anotherSprite^.position.h := anotherSprite^.position.h - moveH;
- frac := frac + absV;
- If frac > absH Then
- begin
- theSprite^.position.v := theSprite^.position.v + moveV;
- anotherSprite^.position.v := anotherSprite^.position.v - moveV;
- frac := frac - absH;
- End;
- End
- Else
- begin
- theSprite^.position.v := theSprite^.position.v + moveV;
- anotherSprite^.position.v := anotherSprite^.position.v - moveV;
- frac := frac + absH;
- If frac > absV Then
- begin
- theSprite^.position.h := theSprite^.position.h + moveH;
- anotherSprite^.position.h := anotherSprite^.position.h - moveH;
- frac := frac - absV;
- End;
- End;
-
- nowVector.h := theSprite^.position.h - anotherSprite^.position.h;
- nowVector.v := theSprite^.position.v - anotherSprite^.position.v;
- Until LongInt(nowVector.h) * nowVector.h + LongInt(nowVector.v) * nowVector.v > kBallDiameterSquared;
- End; (*SeparateBalls*)
-
-
-
- Procedure MoveSprite(theSprite:SpritePtr);
- begin
- theSprite^.speed.v := theSprite^.speed.v + 1; { Simple gravity}
- theSprite^.fixedPointPosition.h := theSprite^.fixedPointPosition.h + theSprite^.speed.h;
- theSprite^.fixedPointPosition.v := theSprite^.fixedPointPosition.v + theSprite^.speed.v;
- theSprite^.position.h := BSR(theSprite^.fixedPointPosition.h, 4);
- theSprite^.position.v := BSR(theSprite^.fixedPointPosition.v, 4);
- if KeepOnScreenFixed(theSprite) then ;
- End; (*MoveSprite*)
-
-
- Procedure HitSprite(theSprite:SpritePtr; anotherSprite:SpritePtr);
- var perpendicularHelpLine, parallelHelpLine, p1, p2, n1, n2:Point;
- begin
- {Check for a *real* collision!}
- If RegionHit(theSprite, anotherSprite) Then
- begin
- perpendicularHelpLine.h := theSprite^.position.h - anotherSprite^.position.h;
- perpendicularHelpLine.v := theSprite^.position.v - anotherSprite^.position.v;
- parallelHelpLine.h := perpendicularHelpLine.v;
- parallelHelpLine.v := -perpendicularHelpLine.h;
- {Move them away from each other}
- SeparateBalls(theSprite, anotherSprite);
- {Make the fixed-point positions follow!}
- theSprite^.fixedPointPosition.h := BSL(theSprite^.position.h, 4);
- theSprite^.fixedPointPosition.v := BSL(theSprite^.position.v, 4);
- anotherSprite^.fixedPointPosition.h := BSL(anotherSprite^.position.h, 4);
- anotherSprite^.fixedPointPosition.v := BSL(anotherSprite^.position.v, 4);
-
- {Swap the speed components that are parallell to parallelHelpLine}
- SplitVector(theSprite^.speed, parallelHelpLine, p1, n1);
- SplitVector(anotherSprite^.speed, parallelHelpLine, p2, n2);
-
- anotherSprite^.speed.h := p2.h + n1.h;
- anotherSprite^.speed.v := p2.v + n1.v;
-
- theSprite^.speed.h := p1.h + n2.h;
- theSprite^.speed.v := p1.v + n2.v;
- End; { if RegionHit}
- End; (*HitSprite*)
-
-
- Procedure InitSprites;
-
- var theSprite:SpritePtr;
-
- (*Load all pictures*)
- begin
- firstFace := LoadFaceFromCicn(128); (*cicn resource #128.*)
- secondFace := LoadFaceFromCicn(129); (*cicn resource #129.*)
- thirdFace := LoadFaceFromCicn(130); (*cicn resource #130.*)
-
- (*Create sprites*)
- theSprite := NewSprite;
- theSprite^.face := firstFace;
- SetPt(theSprite^.fixedPointPosition, BSL(100 , 4), BSL(100 , 4));
- SetPt(theSprite^.speed, 1, 16);
-
- theSprite := NewSprite;
- theSprite^.face := secondFace;
- SetPt(theSprite^.fixedPointPosition, BSL(50 , 4), BSL(50 , 4));
- SetPt(theSprite^.speed, 16, 1);
-
- theSprite := NewSprite;
- theSprite^.face := thirdFace;
- SetPt(theSprite^.fixedPointPosition, BSL(150 , 4), BSL(150 , 4));
- SetPt(theSprite^.speed, Rand(7)-3, Rand(7)-3);
- End; (*InitSprites*)
-
- end.
-
-