Retired Document
Important: This sample code may not represent best practices for current development. The project may use deprecated symbols and illustrate technologies and techniques that are no longer recommended.
MoofWars/TSpriteCollection.cp
/* |
File: TSpriteCollection.cp |
Contains: This class represents a group of related Sprites. For example, all of the |
shots fired by a sprite. In general, the various things that happen to |
sprites (moving, drawing, hit testing) all happen to a whole group at a time. |
Written by: Timothy Carroll |
Copyright: Copyright © 1996-1999 by Apple Computer, Inc., All Rights Reserved. |
You may incorporate this Apple sample source code into your program(s) without |
restriction. This Apple sample source code has been provided "AS IS" and the |
responsibility for its operation is yours. You are not permitted to redistribute |
this Apple sample source code as "Apple sample source code" after having made |
changes. If you're going to re-distribute the source, we require that you make |
it clear in the source that the code was descended from Apple sample source |
code, but that you've made changes. |
Change History (most recent first): |
7/2/1999 Karl Groethe Updated for Metrowerks Codewarror Pro 2.1 |
1/23/97 Timothy Carroll Added include for Moofwars.h so that MrC will compile |
8/15/96 Timothy Carroll Initial Release |
*/ |
#include "Moofwars.h" |
#include "TSpriteCollection.h" |
TSpriteCollection::TSpriteCollection(void) |
{ |
fSpriteListHead = NULL; |
} |
TSpriteCollection::~TSpriteCollection(void) |
{ |
TSprite *currentSprite, *nextSprite; |
nextSprite = fSpriteListHead; |
while (nextSprite != NULL) |
{ |
currentSprite = nextSprite; |
nextSprite = currentSprite->fNextSprite; |
// When we delete a group, we make all of the sprites invisible. This kills a warning |
// in the sprite code. |
currentSprite->SetVisibility(kInvisible); |
delete currentSprite; |
} |
} |
void TSpriteCollection::AddSprite (TSprite *theSprite) |
{ |
if (fSpriteListHead == NULL) |
fSpriteListHead = theSprite; |
else |
{ |
theSprite->fNextSprite = fSpriteListHead; |
fSpriteListHead->fPrevSprite = theSprite; |
theSprite->fPrevSprite = NULL; |
fSpriteListHead = theSprite; |
} |
} |
void TSpriteCollection::RemoveSprite (TSprite *theSprite) |
{ |
TSprite *prevSprite, *nextSprite; |
prevSprite = theSprite->fPrevSprite; |
nextSprite = theSprite->fNextSprite; |
if (prevSprite == NULL) |
fSpriteListHead = nextSprite; |
else |
prevSprite->fNextSprite = nextSprite; |
if (nextSprite != NULL) |
nextSprite->fPrevSprite=prevSprite; |
} |
void TSpriteCollection::ProcessSpriteGroup (void) |
{ |
TSprite *currentSprite, *nextSprite; |
nextSprite = fSpriteListHead; |
// Just a comment about the structure of these loops. We get the next |
// sprite before we call process sprite because process sprite can delete |
// the sprite which would throw our iterator off completely. |
// We're using the same structure in all of the other loops as well. However, |
// any routine that is disallowed from destroying a sprite (for example, |
// drawing and erasing should probably never actually destroy a sprite), then |
// we can use a simpler structure: |
/* |
currentSprite = fSpriteListHead; |
while (currentSprite != NULL) |
{ |
currentSprite->foo(); |
currentSprite = currentSprite->fNextSprite; |
} |
*/ |
while (nextSprite != NULL) |
{ |
currentSprite = nextSprite; |
nextSprite = currentSprite->fNextSprite; |
currentSprite->ProcessSprite(); |
} |
} |
// HitTest routine currently uses some of the inner knowledge of how TSprite works. |
// So if TSprite is modified, this routine may need to be altered. This is an ugly |
// routine, and I only do it here to cache some information. I need to test and see |
// if these optimizations are doing anything. |
void TSpriteCollection::HitTest (TSpriteCollection *targetGroup) |
{ |
TSprite *currentTarget, *nextTarget, *currentSprite, *nextSprite; |
TGraphic *targetGraphic, *spriteGraphic; |
SInt32 targV, targH, spriteV, spriteH; |
nextTarget = targetGroup->fSpriteListHead; |
nextSprite = this->fSpriteListHead; |
// quick short circuit |
if (nextTarget == NULL || nextSprite == NULL) |
return; |
while (nextTarget != NULL) |
{ |
currentTarget = nextTarget; |
nextTarget = currentTarget->fNextSprite; |
if (currentTarget->GetVisibility () == kInvisible) |
continue; |
targH = (currentTarget->fCoordX >> 16) - currentTarget->fXOffset; |
targV = (currentTarget->fCoordY >> 16) - currentTarget->fYOffset; |
targetGraphic = currentTarget->fSpriteImages->GetTGraphic(currentTarget->fFace); |
nextSprite = this->fSpriteListHead; |
while (nextSprite != NULL) |
{ |
currentSprite = nextSprite; |
nextSprite = currentSprite->fNextSprite; |
if (currentSprite->GetVisibility () == kInvisible) |
continue; |
spriteH = (currentSprite->fCoordX >> 16) - currentSprite->fXOffset; |
spriteV = (currentSprite->fCoordY >> 16) - currentSprite->fYOffset; |
spriteGraphic = currentSprite->fSpriteImages->GetTGraphic(currentSprite->fFace); |
if (TGraphic::Intersect (targetGraphic, spriteGraphic, targV,targH,spriteV,spriteH)) |
{ |
currentTarget->Collision(currentSprite); |
currentSprite->Collision(currentTarget); |
} |
} |
} |
} |
void TSpriteCollection::DrawSpriteGroup (void) |
{ |
TSprite *currentSprite, *nextSprite; |
nextSprite = fSpriteListHead; |
while (nextSprite != NULL) |
{ |
currentSprite = nextSprite; |
nextSprite = currentSprite->fNextSprite; |
currentSprite->DrawSprite(); |
} |
} |
Copyright © 2003 Apple Computer, Inc. All Rights Reserved. Terms of Use | Privacy Policy | Updated: 2003-10-14