MoofWars/TSprite.h

/*
    File:       TSprite.h
 
    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
                
                8/15/96     Timothy Carroll Initial Release
                
 
*/
#ifndef _TSPRITE_
#define _TSPRITE_
 
#pragma once
 
#include "TGraphicCollection.h"
#include "Scaling.h"
 
#if PRAGMA_STRUCT_ALIGN
#pragma options align=power
#endif
 
 
 
enum eVisibleFlag
{
    kInvisible = 0,  // An invisible sprite can't be hit tested or drawn.
    kVisible = 1
};
 
 
 
 
 
// When creating a new TSprite, you fill in a TSpriteData structure and pass it along
// to the TSprite constructor.  Two constructors are provided, one that takes a
// TSpriteData pointer and one that takes a TSpriteData handle.
 
// The handle allows a nice method we can use to create a sprite from resource data.
// Note that the TSprite constructor and any follow up constructors should not modify
// the data passed back into it.  We'll define them as const parameters in th
// constructor to enforce this.
 
// All the handle based constructor will do is dereference the handle and pass it in.
// We'll lock and unlock the handle over the call.
 
struct TSpriteData {
 // A 4 character type used to describe the sprite.  Each sprite class will register
 // a OSType that can be used to create a sprite of that type.  Each subclass should
 // also define a Data type that is used to define its parameters (each adding to the
 // previous subclasses's data, obviously.
 
 // If you know what type of sprite you are creating, you can call the constructor
 // directly.  Eventually, I'll try to provide a global creator that can be called with
 // a data structure that will call the appropriate creator based on the spriteType field.
 
 
    OSType              spriteType; 
    SInt32              initialX; // sprite's location in world coordinates
    SInt32              initialY;
    SInt32              initialXVelocity; // sprite's velocity in world coordinates
    SInt32              initialYVelocity;
    SInt16              visibility;         // initial visibility
    SInt16              face;               // initial face
    
    // Graphics to use for the sprite.
    //If the sprites are already loaded, then we can pass in a copy of the TGraphicCollection
    //directly.  If the sprites weren't loaded, preloadedCollection should be set to NULL.
    //If it is NULL, then the resource ID of the collection must be passed in via collectionID.
    //We do this to provide a fast way to make sprites without all the load time.
    SInt16              collectionID;       
    TGraphicCollection  *preloadedCollection;
};
 
 
// Scaling and clipping -- old stuff to be replaced.
 
/* 
// This data structure is used to pass in all of the scaling information needed by each
// TSprite.  Unlike the last class, this one we'll actually just define as a pointer -- no
// resource based info. This might be a mistake, we can change it easily enough.
 
// Note that the point passed in via worldPt is mapped to the exact center of whatever Rect
// is passed in.  This Rect is also the one used to set the clipping for the TGraphic class.
struct TScalingData {
    WorldPoint32    worldPt;
    SInt32          scale;
    Rect            screenRect;
};
 
extern WorldRect32 gScreenBounds;
 
*/
 
class TSpriteCollection;
class TSprite;
 
 
 
class TSprite
{
    // TSpriteCollection is declared as a friend class because it needs direct access to 
    // the "fNextSprite" and fPrevSprite members.  In the current implementation, we also use
    // it in the hit testing code, although this will hopefully be changed in the future because
    // I don't particularly like it. 
 
    friend TSpriteCollection;
    
    
    public:
    
    enum {
        kSpriteType = 'SPRT'
    };
    
 
    
    protected:
 
    // This stores all the data for the sprite's current location and visibility.
    SInt32              fCoordX;        // 16.16 fixed
    SInt32              fCoordY;        // 16.16 fixed
 
    SInt32              fVelocityX; // 16.16 fixed
    SInt32              fVelocityY; // 16.16 fixed
 
    UInt16              fFace;
    UInt16              fVisibility;
    
    Rect                fBounds; // Cache this here rather than in the graphic collection.
    SInt32              fXOffset;
    SInt32              fYOffset; // used when drawing to move to the upper left corner.
    
    // These store the graphic collections we need to draw our sprites.
    TGraphicCollection  *fSpriteImages;
    
    // These are used to maintain sprite groups.  fNextSprite and fPrevSprite
    // are used by the owning TSpriteCollection and should not be touched by the Sprite classes at all.
    
    TSpriteCollection   *fGroup;        // if we are a member of a group, this will be non-null.
    TSprite         *fNextSprite;   // used by TSpriteCollection if we are a group member.
    TSprite         *fPrevSprite;   // used by TSpriteCollection if we are a group member.
 
    
    
    public:
    
/*************************************************************************************
    Constructors and Destructors
    
*************************************************************************************/
    
    TSprite (TSpriteData *data);
    ~TSprite (void);
    
/*************************************************************************************
    Standard Accessor Functions
    
*************************************************************************************/
    
    OSType          GetSpriteType (void) {return kSpriteType;}
    
    void            GetCurrentWorldLocation (SInt32 *worldX, SInt32 *worldY);
    void            SetCurrentWorldLocation (SInt32 worldX, SInt32 worldY);
    
/*  
Boolean
TSprite::GetCurrentScreenLocation (Rect *currentRect)
{
#pragma unused (currentRect)
 
    DebugStr ("\pNot implemented");
    return false;
}
*/
    
    
    SInt16          GetFace() {return fFace;}
    void            SetFace (SInt16 newFace) {fFace = newFace;}
    
    SInt16          GetVisibility () {return fVisibility;}
    void            SetVisibility (SInt16 newVisibility) {fVisibility = newVisibility;}
 
    SInt32          GetXVelocity();
    SInt32          GetYVelocity();
    void            SetXVelocity (SInt32 xVelocity);
    void            SetYVelocity (SInt32 yVelocity);
    
/*************************************************************************************
    Standard Actions that sprites need to do.
*************************************************************************************/
 
    // Drawing takes the sprite's location relative to the scaling values and draws it
    // to the current buffer.  Usually called by the TSpriteCollection automatically.
    
    void DrawSprite (void);
    
    // Each sprite will have its process routine called once per frame -- remember that if
    // things are slowing down, not every frame will be drawn, but all frames will be
    // processed.  Usually called by the TSpriteCollection automatically.
    
    // Default process sprite just moves the sprite according to its velocity.
    virtual void ProcessSprite (void) { fCoordX += fVelocityX; fCoordY += fVelocityY;}
    
    // Whenever two sprites are actually collided, each sprite's collision routine is called
    // with the other as a parameter.  Usually called by the TSpriteCollection automatically.
    virtual void Collision (TSprite *theSprite);
 
/*************************************************************************************
    Utility functions
    
    These aren't automatically called, but are simple utility functions that exist because
    all sprites might need to do them.
    
*************************************************************************************/
    void Bounce (WorldRect32 *bounceBounds);
 
/*************************************************************************************
    These routines add and remove a sprite from a group.  Call these routines, don't call
    the routines from the TSpriteCollection class -- they only exist for these functions to
    call.  If you call the TSpriteCollection routines, then parameters in the TSprite class don't
    always get set properly.
    
*************************************************************************************/
        
    void AddToGroup (TSpriteCollection *theGroup);
    void RemoveFromGroup (void);
 
/*************************************************************************************
    These routines are used to set all the clipping information
    These routines set the scaling information and coordinate system.  It also sets the
    appropriate clipping rectangle in the TGraphic class.  It doesn't change the GWorld
    pointed to by the TGraphic and the caller must make sure this rectangle is within the
    GWorld's actual rectangle or bad things will happen.
    
*************************************************************************************/  
 
};
    
 
#if PRAGMA_STRUCT_ALIGN
#pragma options align=reset
#endif
 
 
 
#endif /* _TSPRITE_ */