Main Page | Namespace List | Class Hierarchy | Alphabetical List | Data Structures | File List | Data Fields | Globals | Related Pages

CSSprite.h

Go to the documentation of this file.
00001 #ifndef CSSPRITE_H
00002 #define CSSPRITE_H
00003 
00004 // USES SDL_Surface
00005 
00006 #include <string>
00007 #include <vector>
00008 #include <map>
00009 #include "CSTypes.h"
00010 #include "CSLoadable.h"
00011 #include "CSMessageListener.h"
00012 #include "CSMessage.h"
00013 #include "CSAction.h"       //!< for ActionState
00014 #include "CSLog.h"
00015 
00016 class CSTileMap;
00017 class CSTile;
00018 class CSNavigator;
00019 
00020 class CSSpriteLoader;
00021 class CSSprite;
00022 class StateData;
00023 class ActionBundle;
00024 
00025 typedef std::vector<CSSprite*> CSSprites;
00026 typedef std::vector<StateData *> StateDatas;
00027 typedef std::map<int, ActionBundle *> ActionBundleMap;
00028 
00029 class StateData
00030 {
00031 public:
00032         StringVector actionNames;           //!< filenames (xml) of all action belonging to sprite
00033         char *defaultActionName;            //!< default action (id)
00034         int stateId;
00035         
00036         StateData()
00037         {
00038             defaultActionName = 0;
00039             stateId = 0;
00040         }
00041 
00042         ~StateData()
00043         {
00044             for (StringVector::iterator iter = actionNames.begin(); iter != actionNames.end(); iter++)
00045             {
00046                 delete *iter;
00047             }
00048             actionNames.clear();
00049 
00050             if (defaultActionName != 0)
00051             {
00052                 free(defaultActionName);
00053                 defaultActionName = 0;
00054             }
00055             stateId = 0;
00056         }
00057 };
00058 
00059 //! data classes are used for loading a loadable class
00060 //! first the data is loaded via xml into this "DATA"-class
00061 //! from this data - the actual sprite is created
00062 //! the data can be reused to create another instance of an
00063 //! sprite class - though probably not needed...
00064 class CSSpriteData
00065 {
00066     public:
00067         char *id;                           //!< id of sprite (unique)
00068         StateDatas stateDatas;
00069         int layer_position;                 //!< sprite lies above layer (and under each higher layer)
00070         int type;
00071         int defaultBundle;
00072         int subtype;
00073         int y_position;                     //!< within that layer a sprite can have a y position
00074                                             //!< so that one sprite can be above another within one layer
00075                                             //!< TODO: right now the squence of the sprite
00076                                             //!< is used, this parameter is still ignored!
00077         CSSpriteData()
00078         {
00079             type = 0;
00080             subtype = 0;
00081             defaultBundle = 0;
00082             id = 0;
00083             layer_position = 0;
00084             y_position = 0;
00085         }
00086 
00087         ~CSSpriteData()
00088         {
00089             if (id != 0)
00090             {
00091                 free (id);
00092                 id = 0;
00093             }
00094             for (StateDatas::iterator iter = stateDatas.begin(); iter != stateDatas.end(); iter++)
00095             {
00096                 delete *iter;
00097             }
00098             stateDatas.clear();
00099         }
00100 };
00101 
00102 //! the states hold all variable parts needed for printing the 
00103 //! sprite on screen
00104 //! putting these in a state class, enables us to
00105 //! reuse the memory expensive sprite class!
00106 class SpriteState
00107 {
00108     public:
00109         ActionState mActionState;       //!< each sprite must have actions -> so each
00110                                         //!< sprite state needs an action state!
00111 
00112         //!< current active action
00113         CSAction *mCurrentAction;
00114         ActionBundle *mCurrentBundle;
00115         int mCurrentBundleId;
00116         int mUserState;
00117 
00118         SpriteState() 
00119         {
00120             mUserState = 0;
00121             mCurrentAction = 0;
00122             mCurrentBundleId = 0;
00123             mCurrentBundle = 0;
00124         }
00125         virtual ~SpriteState() {}
00126 };
00127 
00128 class ActionBundle
00129 {
00130     public:
00131         CSActions *mActions;            //!< all actions belonging to this sprite
00132         CSAction *mDefaultAction;       //!< default action
00133         int stateId;
00134 
00135         ActionBundle()
00136         {
00137             mActions = 0;           //!< all actions belonging to this sprite
00138             mDefaultAction = 0;     //!< default action
00139             stateId = 0;
00140         }
00141         
00142         ~ActionBundle()
00143         {
00144             if (mActions != 0)
00145             {
00146                 //!< Actions are singletons -> do not delete them 
00147                 delete mActions;
00148                 mActions = 0;
00149             }
00150             mDefaultAction = 0;
00151         }
00152 };
00153 
00154 /**
00155     This file defines CSSprite:
00156 
00157       CSSprite can only be created thru a loader (CSSpriteLoader).
00158       CSSprite are defined by (now ONLY thru) an xml-File, like:
00159       DTD:
00160 \verbatim
00161         <!ELEMENT SPRITE (ID,(ACTION)+,DEFAULT_ACTION,LAYER_POSITION,Y_POSITION)>
00162         <!ELEMENT ID (#PCDATA)>
00163         <!ELEMENT ACTION (#PCDATA)>
00164         <!ELEMENT DEFAULT_ACTION (#PCDATA)>
00165         <!ELEMENT LAYER_POSITION (#PCDATA)>
00166         <!ELEMENT Y_POSITION (#PCDATA)>
00167 \endverbatim
00168       Example:
00169 
00170 \verbatim
00171           <SPRITE>
00172             <ID>PACMAN_SPRITE</ID>
00173             <ACTION>action\\pac_down.xml</ACTION>
00174             <ACTION>action\\pac_up.xml</ACTION>
00175             <ACTION>action\\pac_left.xml</ACTION>
00176             <ACTION>action\\pac_right.xml</ACTION>
00177             <ACTION>action\\pac_down_stay.xml</ACTION>
00178             <ACTION>action\\pac_up_stay.xml</ACTION>
00179             <ACTION>action\\pac_right_stay.xml</ACTION>
00180             <ACTION>action\\pac_left_stay.xml</ACTION>
00181             <ACTION>action\\pac_death.xml</ACTION>
00182             <DEFAULT_ACTION>action\\pac_right.xml</DEFAULT_ACTION>
00183             <LAYER_POSITION>0</LAYER_POSITION>
00184             <Y_POSITION>0</Y_POSITION>
00185         </SPRITE>
00186 \endverbatim
00187 <PRE>
00188       ID           - supposed a unique identifier
00189 
00190       ACTION       - many actions are possible!
00191                      describes the action to be loaded,
00192                      parameter gives the ini-file for a CSAction
00193 
00194       DEFAULT_ACTION - an action that is used as a default, if another actions
00195                      ends.
00196                      This default is overriden by the DEFAULT_NEXT_ACTION
00197                      setting of the current active action.
00198                      The default action should not appear listed in the 
00199                      'normal' action setting. (no double entries)
00200 
00201       LAYER_POSITION - sprite lies above layer (and under each higher layer)
00202       Y_POSITION    - within that layer a sprite can have a y position
00203                       so that one sprite can be above another within one layer
00204                       TODO: right now the squence of the sprite
00205                       is used, this parameter is still ignored!
00206 
00207       Methods:
00208         virtual void next();
00209         virtual void display();
00210         SpriteState buildState();                       // only for compatibility issues
00211         void resetState(SpriteState &state);
00212         virtual void reactOnMessage(CSMessage *message);// MessageListener implementation
00213         void setSecPerFrame(float secPerFrame);
00214         void setDisplayOffset(int xOffset, int yOffset);// where on the screen is 0,0 of our displaying 
00215         void setWorldPosition(int x, int y);            // where in the world will we start drawing the screen
00216         unsigned int checkCollisionPixels(CSSprite *other); // Collision detection, returns # of pixels
00217         unsigned int checkCollisionPixels(CSTileMap *map);  // Collision detection, returns # of pixels
00218         unsigned int checkCollisionPixels(CSTile *tile);    // Collision detection, returns # of pixels
00219         bool checkCollision(CSSprite *other);           // Collision detection, returns boolean
00220         bool checkCollision(CSTileMap *map);            // Collision detection, returns boolean
00221         bool checkCollision(CSTile *tile);              // Collision detection, returns boolean
00222         std::vector<CSTile*> getCollidingTiles(CSTileMap *map); // return all tiles, that have pixels colliding with sprite
00223         void setSpeedY(int speed);                      // overrides values in animation
00224         void setSpeedX(int speed);                      // overrides values in animation
00225         void resetSpeed();                              // returns to speed values of animation (default)
00226         SpriteState getState() 
00227         void setState(const SpriteState &state) 
00228         int getLayer() 
00229         int getLayerY() 
00230         void clearNavigator() 
00231         void setNavigator(CSNavigator *navigator)
00232         unsigned int getDisplayXLower()     
00233         unsigned int getDisplayYLower()
00234         unsigned int getDisplayXUpper() // pos + width of sprite
00235         unsigned int getDisplayYUpper() // pos + height of sprite
00236         unsigned int getXPos()  
00237         unsigned int getYPos()
00238 
00239       Supported messages: 
00240       (see Message.h)
00241       Messages of type; ACTION_MESSAGE
00242 
00243       CSSprite also implements:
00244             CSMessageListener
00245 </PRE>
00246     the sprite class has (in opposite to action an aniamtion) state 
00247     dependent data -> the sprite state
00248     should at some point it be neccessary to have state information outside of
00249     sprites - than we must remove it here, than the sprite class will
00250     (as action and aniamtion) behave as a local singleton... (and change next(), display())
00251     */
00252 class CSSprite : public CSMessageListener, public CSMessageDispatchable
00253 {
00254     friend CSSpriteLoader;
00255     private:
00256         SpriteMessage MESSAGE_SPRITE_ACTION_CHANGE;
00257         SpriteState mState;             //!< the only state dependent data within this class
00258 
00259         bool mActive;
00260         ActionBundleMap actionMap;
00261         int mDefaultBundle;
00262         CSNavigator *mNavigator;        //!< this class can 'navigate' our sprite (if set)
00263                                         //!< called within (at first chance) next()
00264         int mType;
00265         int mSubtype;
00266         int layer_position;             //!< sprite lies above layer (and under each higher layer)
00267         int y_position;                 //!< within that layer a sprite can have a y position
00268                                         //!< so that one sprite can be above another within one layer
00269                                         //!< TODO: right now the squence of the sprite
00270                                         //!< is used, this parameter is still ignored!
00271 
00272         unsigned int mWidth;            //!< max Width of this sprite
00273         unsigned int mHeight;           //!< max Height of this sprite
00274         unsigned int mWorldPos;         //!< current on world #         
00275         std::string mFilename;
00276         char *mId;
00277         //!< constructor using "*.xml" file
00278         CSSprite(const std::string &filename);
00279         static void loadSpriteData(const std::string &filename, CSSpriteData &data);
00280         bool changeStateTo(int state);
00281 
00282         void initialize(const CSSpriteData &data);
00283         void initialize();
00284     
00285     public:
00286         CSSprite(const CSSprite &Sprite);
00287         virtual ~CSSprite();
00288 
00289         static const char *CLASS;
00290         virtual std::string getType() {return (std::string) CLASS;}
00291 
00292         virtual void next();
00293         virtual void display();
00294 
00295         SpriteState buildState();                       //!< only for compatibility issues
00296         void resetState(SpriteState &state);
00297         
00298         virtual void reactOnMessage(CSMessage *message);//!< MessageListener implementation
00299 
00300         void setSecPerFrame(float secPerFrame);
00301         
00302         void setDisplayOffset(int xOffset, int yOffset);//!< where on the screen is 0,0 of our displaying   
00303         void setWorldPosition(int x, int y);            //!< where in the world will we start drawing the screen
00304         unsigned int checkCollisionPixels(CSSprite *other); //!< Collision detection, returns # of pixels
00305         unsigned int checkCollisionPixels(CSTileMap *map);  //!< Collision detection, returns # of pixels
00306         unsigned int checkCollisionPixels(CSTile *tile);    //!< Collision detection, returns # of pixels
00307         bool checkCollision(CSSprite *other);           //!< Collision detection, returns boolean
00308         bool checkCollision(CSTileMap *map);            //!< Collision detection, returns boolean
00309         bool checkCollision(CSTile *tile);              //!< Collision detection, returns boolean
00310         std::vector<CSTile*> getCollidingTiles(CSTileMap *map); //!< return all tiles, that have pixels colliding with sprite
00311         void setSpeedY(int speed);                      //!< overrides values in animation
00312         void setSpeedX(int speed);                      //!< overrides values in animation
00313         void adjustSpeed(int speed);                    //!< overrides values in animation
00314         void resetSpeed();                              //!< returns to speed values of animation (default)
00315         void setNavigator(CSNavigator *navigator);
00316         CSNavigator *getNavigator() {return mNavigator;}
00317         void setAlpha(int alpha);
00318 
00319         //!< inlines
00320         unsigned int getWorldPos() {return mWorldPos;}
00321         SpriteState getState() {return mState;}
00322         void setState(const SpriteState &state) {mState = state;}
00323         void setLayer(int z) {layer_position = z;}
00324         int getLayer() {return layer_position;}
00325         int getLayerY() {return y_position;}
00326         void clearNavigator() {mNavigator = 0;}
00327         void resetNavigator();
00328         int getMaxWidth() {return mWidth;}
00329         int getMaxHeight() {return mHeight;}
00330         int getSpriteType() {return mType;}
00331         int getSubtype() {return mSubtype;}
00332         int getCurrentStateId() {return mState.mCurrentBundleId;}
00333         std::string getFilename() {return mFilename;}
00334         std::string getId() {return mId;}
00335         void setPosition(int x, int y, unsigned int z);
00336 
00337         int getUserState(void) {return mState.mUserState;}
00338         void setUserState(int userState) {mState.mUserState = userState;}
00339 
00340         SDL_Surface *getScaledSprite(double factor)
00341         {
00342             return mState.mActionState.mAnimation->getScaledAnimation(mState.mActionState.mAnimationState, factor);
00343         }
00344 
00345         const char *getCurrentActionId()
00346         {
00347             return mState.mCurrentAction->getId();
00348         }
00349         int getCurrentActionType()
00350         {
00351             return mState.mCurrentAction->getActionType();
00352         }
00353 
00354         
00355         //!< return x start of surface coordinates of where the
00356         //!< the sprite will be drawn during next display
00357         unsigned int getDisplayXLower()     
00358         {
00359             int x = 
00360                 mState.mActionState.mAnimationState.mDisplayParams.mXDisplayStart + 
00361                 mState.mActionState.mAnimationState.mDisplayParams.mXPos -
00362                 mState.mActionState.mAnimationState.mDisplayParams.mXWorldStart;
00363             return x;
00364         }
00365 
00366         //!< return y start of surface coordinates of where the
00367         //!< the sprite will be drawn during next display
00368         unsigned int getDisplayYLower()
00369         {
00370             int y = 
00371             mState.mActionState.mAnimationState.mDisplayParams.mYDisplayStart + 
00372             mState.mActionState.mAnimationState.mDisplayParams.mYPos -
00373             mState.mActionState.mAnimationState.mDisplayParams.mYWorldStart;
00374             return y;
00375         }
00376 
00377         //!< return x end of surface coordinates of where the
00378         //!< the sprite will be drawn during next display
00379         unsigned int getDisplayXUpper() //!< pos + width of sprite
00380         {
00381             int x = getDisplayXLower();
00382             x += mWidth;
00383             return x;
00384         }
00385 
00386         //!< return y end of surface coordinates of where the
00387         //!< the sprite will be drawn during next display
00388         unsigned int getDisplayYUpper() //!< pos + height of sprite
00389         {
00390             int y = getDisplayYLower();
00391             y += mHeight;
00392             return y;
00393         }
00394         
00395         //!< return the world x-coordinate of sprite that will be used during
00396         //!< the next display
00397         int getXPos()   
00398         {
00399             return mState.mActionState.mAnimationState.mDisplayParams.mXPos;
00400         }
00401 
00402         //!< return the world y-coordinate of sprite that will be used during
00403         //!< the next display
00404         int getYPos()
00405         {
00406             return mState.mActionState.mAnimationState.mDisplayParams.mYPos;
00407         }
00408         void setActive(bool active) 
00409         {
00410             mActive = active;
00411         }
00412 };
00413 
00414 //! factory - class
00415 //! that is used to create CSSprite
00416 //! uses xml - data-files, produces NOT "singletons"!!!
00417 //! than means the result sprite must be freed by the caller (or whoever)!!!
00418 class CSSpriteLoader : public Loadable<CSSprite>
00419 {
00420     protected:
00421         //! not a singleton created!
00422         virtual bool isSingleCreate(void) const
00423         {
00424             return false;
00425         }
00426 
00427         virtual CSSprite *create(const std::string &filename)
00428         {
00429             return new CSSprite(filename);
00430         }
00431 
00432     public:
00433         static CSSpriteLoader INSTANCE;
00434 };
00435  
00436 #endif // CSSPRITE_H
00437 

Generated on Wed Jul 14 00:43:42 2004 for CSLib by doxygen 1.3.6