MoofWars/TSprite.cp

/*
    File:       TSprite.cp
 
    Contains:   This implements a first cut at a standardized sprite class.  This is an
                abstract base class and all sprites must be subclassed off a TSprite.
 
    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 "TSprite.h"
#include "TSpriteCollection.h"
#include "DrawSprocket.h"
 
 
/*************************************************************************************
    Constructors and Destructors    
*************************************************************************************/
 
 
TSprite::TSprite (TSpriteData *data)
{
    fCoordX  = data->initialX;
    fCoordY  = data->initialY;
    
    fVelocityX = data->initialXVelocity;
    fVelocityY = data->initialYVelocity;
    
    fFace = data->face;
    fVisibility = data->visibility;
    
    fGroup = NULL;
    fNextSprite = fPrevSprite = NULL;
    
    if (data->preloadedCollection != NULL)
    {
        fSpriteImages = data->preloadedCollection;
        fSpriteImages->AddReference();
    }
    else
        fSpriteImages = TGraphicCollection::NewCollection (data->collectionID);
    
    fBounds = fSpriteImages->GetBounds(0);
    
    fXOffset = (fBounds.right - fBounds.left) >> 1;
    fYOffset = (fBounds.bottom - fBounds.top) >> 1;
}
 
TSprite::~TSprite (void)
{
    if (fSpriteImages)
        fSpriteImages->DisposeReference();
    fSpriteImages = NULL;
    RemoveFromGroup();
}
 
/*************************************************************************************
    Standard Accessor Functions
    
*************************************************************************************/
    
void            
TSprite::GetCurrentWorldLocation  (SInt32 *worldX, SInt32 *worldY)
{
    *worldX = fCoordX;
    *worldY = fCoordY;
}
    
void
TSprite::SetCurrentWorldLocation (SInt32 worldX, SInt32 worldY)
{
    fCoordX = worldX;
    fCoordY = worldY;
}
 
SInt32
TSprite::GetXVelocity()
{
    return fVelocityX;
}
 
SInt32
TSprite::GetYVelocity()
{
    return fVelocityY;
}
 
void
TSprite::SetXVelocity (SInt32 xVelocity)
{
    fVelocityX = xVelocity;
}
 
void
TSprite::SetYVelocity (SInt32 yVelocity)
{
    fVelocityY = yVelocity;
}
 
 
void
TSprite::DrawSprite (void)
{
    // calculate the top left corner of the current world coordinates given our scaling
    // information.  We pass this along to the TGraphic for the current scale.  It is considered
    // an error to draw in a scale that has no collection of graphics.
    
    if (fVisibility == kVisible)
    {
        // convert to QD coordinates
        SInt32              spriteH, spriteV;
 
#if qDebugging
        if (fSpriteImages == NULL)
        {
            DebugStr ("\pAttempted to draw with an invalid scale");
            return;
        }
#endif
 
// The ability to draw the sprite in different sizes is nice, but it might cause too much
// overhead.  Need to test this.
        
        spriteH = ((fCoordX - gWorldCoordX) >> 16) + gClipCenterX - fXOffset;
        spriteV = ((fCoordY - gWorldCoordY) >> 16) + gClipCenterY - fYOffset;
 
        fSpriteImages->CopyImage (fFace, spriteV, spriteH, kDrawGraphic);
    }
}
 
 
void
TSprite::Bounce (WorldRect32 *bounceBounds)
{
    SInt32 xOff = fXOffset << 16;
    SInt32 yOff = fYOffset << 16;
    
    if (((fCoordX-xOff < bounceBounds->left) && (fVelocityX < 0)) ||
        ((fCoordX+xOff > bounceBounds->right) && (fVelocityX > 0)))
    {
        fVelocityX = -fVelocityX;
        fCoordX += fVelocityX;
    }
 
    if (((fCoordY-yOff < bounceBounds->top) && (fVelocityY < 0)) ||
        ((fCoordY+yOff > bounceBounds->bottom) && (fVelocityY > 0)))
    {
        fVelocityY = -fVelocityY;
        fCoordY += fVelocityY;
    }
 
}
 
 
void
TSprite::Collision (TSprite *theSprite)
{
#pragma unused (theSprite)
    // by default we do nothing in a collision
}
 
 
/*************************************************************************************
    Routines that link up with the TSpriteCollection class.  Note that these routines should
    always be called.  Don't call the routines in the TSpriteCollection class, or things won't
    be updated properly.
    
*************************************************************************************/
        
void
TSprite::AddToGroup (TSpriteCollection *theGroup)
{
    // clear any existing group
    RemoveFromGroup();
    theGroup->AddSprite (this);
    fGroup = theGroup;
}
 
void
TSprite::RemoveFromGroup (void)
{
    if (fGroup != NULL)
    {
        fGroup->RemoveSprite(this);
        fGroup = NULL;
    }
}