/* $Id: wopsprites.hpp,v 1.17 2005/06/28 13:55:26 chfreund Exp $ */ #ifndef WOP_GRAPHICS_CLASS_DEFINED #define WOP_GRAPHICS_CLASS_DEFINED /**********************************************************/ #include "constants.hpp" #include "random.hpp" #include "spriteset.hpp" class Object; /**********************************************************/ //! the interface for class WopSprites, that is visible inside class World class WopSpritesWorldInterface { public: virtual ~WopSpritesWorldInterface( void ) {}; virtual int getSequenceLength( const Object& object ) const = 0; virtual int getNumSequences( const Object& object ) const = 0; virtual int getSequenceLength( const Sint32 id, const Sint32 iseq ) const = 0; virtual void removeColoredInstance( Object& object ) = 0; protected: WopSpritesWorldInterface() {}; }; /**********************************************************/ //! The class, that organizes all sprites for the game /*! WopSprites in a nutshell:
* - one sprite (class Sprite), i.e. one picture, that is drawn on * the screen, is called a frame. * - several frames, organized as a vector of pointers pointing to * them (class PointerVector) a called an animation sequence, or * just sequence (class SpriteSequence). * - again a PointerVector of sequences is called a sprite * set (class SpriteSet) or just set. * - and, once again, a PointerVector of sprite sets builds * the WoP sprites (class WopSprites). * * If an object should be drawn, the class WopSprites must select the * appropriate sprite (== frame). * * - Therefore first the correct sprite set must be selected. * The set belonging to an object is simply determined by * its object ID (see class Object). This ID is the access index * in the pointer vector of sprite sets in the WoP Sprites. * - Furthermore an objects keeps an index of its current sequence * and of the current frame in this sequence. * * There are also objects, like for example the avatars, that exist * inside the game in differently colored versions. The strategy of * WoP is to load each frame of such sprite sets as one * ore more layers. Then these layers are colored separately and * combined into a specificly colored single frame (also see * Sprite::colorGrayPixels and SpriteSet::getColoredInstance). Such * sprite set, that must be colored and built before usage, is * called templated and the readilly colored set is * called a colored instance or just an instance. If * a set is templated, it additionally keeps all its * instances. Therefore we can ask a templated set for * an instance specified by an array of colors (with at least * the length equal to the number of layers). *
* Therefore an object, that uses a templated set, must implement the * methods Object::getColors and Object::getNumColors (for an example * see class AvatarWorm). All objects provide the interface * Object::setInstance, Object::getInstance. These functions are only * used by class WopSprites to store and receive the index of the * instance inside the vector of instances. Now we can answer the * question ... *
* * How is an object drawn by class WopSprites?:
* - WopSprites retrieves the object's ID and selects the corresponding * sprite set. * - If this set is templated, WopSprites asks the object for * the instance index. If this index is < 0, the index is saught * using the colors of the object. If a matching instance is not * yet built, it is tried to be created. After that we have a pointer * to a usable sprite set, either a colored instance * or an original set. * - In the finally determined set the sequence and frame is * selected and drawn, using the indices got from the object. * * Why is WopSprites a class template?
* Although WopSprites only represents the graphic sets for all objects, * it influences the events in the world, nevertheless. For example an * explosion lives as long, as the last frame of the explosion sequence * is not drawn. Therefore the sequence length limits the life time of * the explosion object. This information must be accessible on the * client as well as on the server. But it would not be a proper * implementation to load all graphics on the server, too. Therefore * the WopSprite object is instantiated with a dummy sprite class, * which supports the full interface of class Sprite, but implements * no functionality. The result is a fully working WopSprite instance * with a behaviour identical to the one of the client's version, with * the only difference, that not a single graphic is loaded or drawn. * * The configuration file
* The configuration file for the WoP's graphic set has got only one * setting, namely "pathconfigpairs". To this setting pairs of strings * must be assigned. Each of these pairs consist of
* (1) path to the configuration file of the sprite set (path, * relative to the path, where this file is placed)
* (2) name of the configuration file, that defines the sprite * sequence. This mentioned file must be found in the path * defined in part (1) *
* example for the configuration file:
*
* \code * pathconfigpairs = explosions, explosion_small.config, \ * explosions, explosion_medium.config, \ * explosions, explosion_big.config, \ * magic, flashes * \endcode */ template class WopSprites : private PointerVector< SpriteSet >, public WopSpriteSettingDefs, public WopSpritesWorldInterface { public: WopSprites(); virtual ~WopSprites(); // implementation for the interface routines int getSequenceLength( const Object& object ) const; int getNumSequences( const Object& object ) const; int getSequenceLength( const Sint32 id, const Sint32 iseq ) const; //! \name access to the underlying data //!@{ //! returns a pointer to the SpriteSet for the object ID "objectID" /*! Since the objectID does not contain any further information * in colored case the basic SpriteSet is returned, not the * colored instance. */ inline const SpriteSet* getSet( const int objectID ) const; //! returns a pointer to the SpriteSet belonging to the passed object. /*! If the set is templated and the object supports coloring, * the according instance is returned (which is built, if * not already present AND "create" is set to true) */ inline const SpriteSet* getSet( Object& object, const bool create = true ); /*! pointer to the SpriteSet object, that represents the * colored instance with index "instance" for object ID * "objectID" */ inline const SpriteSet* getColorInstance( const int objectID, const int instance ) const; /*! pointer to the SpriteSet obhect, that represents the * colored instance of object ID "objectID" with colors at * "colors". If "create" is set to true, the class will try * to create the instance, if not already present. */ inline const SpriteSet* getColorInstance( const int objectID, const Uint32* const colors, const bool create = true ); /*! pointer to the SpriteSequence object, that is sequence with * index "sequence" in the sprite set with ID "objectID" */ inline const SpriteSequence* getSequence( const int objectID, const int sequence ) const; /*! pointer to the Sprite object, that is frame with index * "frame" in sequence "sequence" in the set of ID "objectID" */ inline const T* getSprite( const int objectID, const int sequence, const int frame ) const; //! pointer to the Sprite object, according to the passed object const T* getSprite( const Object& object, Sint32* nextSequence = NULL, const bool create = true ); //! removes and destroys the specified colored instance void removeColoredInstance( Object& object ); //!@} void reset(); // load graphics bool load( ProgressLog* const progresslog = NULL ); bool load( const char* const BasePath, const char* const ConfigFile, ProgressLog* const progressloog = NULL ); //! draws the passed object on the surface /*! This function draws the passed object on the passed surface. * If the object supports color and the found sprite set is * templated, the according instance is sought and created, if * not found. * \param object the object that should be drawn * \param surface the SDL_Surface, the object sould be drawn on * \return the index of the next frame. Set this new frame * index in the object, if you want the animation to be * continued */ int draw( Object& object, SDL_Surface *const surface ); //! draws the passed object on the surface /*! This function draws the passed object on the passed surface. * If the object supports color and the found sprite set is * templated, the according instance is sought and created, if * not found. The object is drawn at the passed position (x,y), * i.e. the coordinates of the object are ignored. * \param object the object that should be drawn * \param surface the SDL_Surface, the object sould be drawn on * \return the index of the next frame. Set this new frame * index in the object, if you want the animation to be * continued */ int draw( Object& object, const int x, const int y, SDL_Surface *const surface ); //! enum { CHOOSE_RANDOM_SEQUENCE = -1 }; }; /**********************************************************/ #endif // WOP_GRAPHICS_CLASS_DEFINED