/*************************************************************************** kspritecache.h ------------------- begin : September 2001 by Martin Heni email : martin@heni-online.de ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef _KSPRITECACHE_H #define _KSPRITECACHE_H #include #include class TDEConfig; class KSprite; /** * this is an internal class to provide a @ref TQObject to emit * a signal from a sprite if a notify object is created * You do not need this directly. * TODO: Can be part of the KSprite class **/ class KSpriteNotify : public TQObject { Q_OBJECT public: KSpriteNotify() :TQObject(0,0) {mRefCnt=0;} void emitSignal(TQCanvasItem *parent,int mode) {emit signalNotify(parent,mode);} void incRefCnt() {mRefCnt++;} void decRefCnt() {mRefCnt--;} int refCnt() {return mRefCnt;} signals: void signalNotify(TQCanvasItem *,int); private: int mRefCnt; }; class KSpriteMove { public: KSpriteMove() {} virtual ~KSpriteMove() {} virtual bool spriteMove(double ,double ,KSprite *) {return false;} private: }; /** * The KSprite class is an advance TQCanvasSprite class which * is usable with the @ref KSpriteCache. It furthermore contains a * few useful functions like advanced movement and animations which * go beyond the TQCanvasSprite versions of them. Also it provides * a signal which is emitted when movement or animation are finished. * * @short The main TDE game object * @author Martin Heni * */ class KSprite : public TQCanvasSprite { public: /** * Contructs a KSprite object. It is anlogous to the @ref TQCanvasSprite * constructor * * @param array - the frames of the sprite * @param canvas - the canvas the sprites lives on **/ KSprite(TQCanvasPixmapArray* array, TQCanvas* canvas); /** * Destructs the sprite **/ virtual ~KSprite(); /** * The sprites runtime idendification (32) **/ int rtti() const {return 32;} /** * returns a pointer to the pixmap array which holds the * frames of the sprite. **/ TQCanvasPixmapArray* images() const {return mImages;} /** * Moves the sprite to the given position with the given speed. * When it reaches its desitnation a signal is emmited if the * emmiter @ref createNotify is enabled * * @param x - the x coordinate * @param y - the y coordinate * @param speed - the speed to move . If zero the last set speed is taken **/ void moveTo(double x,double y,double speed=0.0); /** * Generates a linear move to the target tx,ty from the current * position of the sprite with its set speed @ref setSpeed * Upon arrival the function returns false to indicate an end of the * movment. Otherwise true is returned. * The sprite is moved in this function. **/ bool spriteMove(double tx,double ty); /** * The sprites advance function. See the qt @ref QcanvasSprite advance **/ void advance(int stage); /** * Sets the speed for the next move. Can be set with moveTo too. * * @param v - the speed in pixel per animation cycle **/ void setSpeed(double v) {mSpeed=v;} /** * returns the speed **/ double speed() {return mSpeed;} /** * returns the notification TQObject. You probably do not need this but * @ref createNotify instead **/ TQObject *notify() {return (TQObject *)mNotify;} /** * Directly emits the notification signal with the given parameter * * @param the notification parameter **/ void emitNotify(int mode); /** * Creates a notification object. You can connect to it and it will emit * the signal signalNotify(TQCanvasItem *parent, intmode) when a move or * animation is finished. * Example: *
    *  connect(sprite->createNotify(),TQT_SIGNAL(signalNotify(TQCanvasItem *,int)),
    *          this,TQT_SLOT(moveDone(TQCanvasItem *,int)));
    * 
* In the move done function you best delete the notify again with * @ref deleteNotify **/ TQObject *createNotify(); /** * Deletes the sprite notify if it is no longer used. The notify keeps a * reference count which deletes the TQObject when no reference to it is in * use. **/ void deleteNotify(); /** * Reads the animation parameters into the given variables for the given * animation. Mostly used by @ref KSpriteCache * * @param no - the animation number * @param startframe - the first frame of the animation * @param endframe - the last frame of the animation * @param mode - the mode of the animation see @ref creaetAnimation * @param delay - the delay in TQCanvas animation cycles between two frames **/ void getAnimation(int no,int &startframe,int &endframe,int &mode,int &delay); /** * Creates an animation of the sprite between two frames in one of the * following modes * 0: no animation * 1: single shot a->b *-1: single shot b->a * 2: cycle a->b->a *-2: cycle b->a->b * 3: cycle a->b *-3: cycle b->a * * The single shot animations will emit the above mentioned signal over the * notify object if it is created. * If you load the sprite over the KSpriteCache's config file you need not * bother about calling this function. **/ void createAnimation(int no,int startframe,int endframe,int mode,int delay); /** * Switches on the animation of the given number. Of course it needs to be * defined beforehand either via loading the sprite with the * @ref KSpriteCache or be calling @ref createAnimation * * @param no - the number of the animation **/ void setAnimation(int no); /** * Returns how many different animations are stored **/ unsigned int animationCount() {return mAnimFrom.count();} void setMoveObject(KSpriteMove *m) {mMoveObj=m;} KSpriteMove *moveObject() {return mMoveObj;} protected: KSpriteMove *mMoveObj; private: KSpriteNotify *mNotify; TQCanvasPixmapArray* mImages; TQByteArray mAnimFrom; TQByteArray mAnimTo; TQByteArray mAnimDirection; TQByteArray mAnimDelay; double mTargetX,mTargetY; double mSpeed; int mAnimationNumber; int mAnimSpeedCnt; int mCurrentAnimDir; }; /** * The KSpriteCache class is used to load and cache sprites. Loading * is done via a @ref TDEConfig file which contains the definitions of the * sprite in text form. Usng this approach allows you to tun the sprites * without chaning the sourcecode of the program. This is especially useful if * the graphics team is independent of the programmer or if you want to write * external themes for your game. * Furhtermore the class keeps sprites in memory so that they are fastly * reloaded when you use more than one sprite of a given type. * * Example: *
 * # Sprite with three frames and a common mask for them
 * # z position given but x,y set manually in the program
 *  [arrow]
 *  file=arrow%d.png
 *  mask=arrow_mask.png
 *  number=3
 *  offset=19,5
 *  rtti=32
 *  z=9.0
 *
 * # Simple sprite which is already positioned correcly. No mask just one file
 *  [board]
 *  file=board.png
 *  rtti=32
 *  x=15.0
 *  y=40.0
 *  z=0.0
 * 
 * # Sprite with one cyclic (2) animation of  5 frames (0-4) and
 * # a slow delay of 8
 *  [star]
 *  anim0=0,4,2,8
 *  file=star%d.png
 *  mask=star%d_mask.png
 *  number=5
 *  offset=19,20
 *  rtti=32
 *  z=100.0
 *
 * 
* * @todo Support single sprites (only one copy in memory) * Support more sprite types (currently KSprite and TQCanvasText) * * @short The main TDE game object * @author Martin Heni * */ class KSpriteCache : public TQObject { Q_OBJECT public: /** * Create a sprite cache. Usuzally you will need one per program only. * * @param grafixdir - the directory where the configuration file and the graphics reside **/ KSpriteCache(TQString grafixdir, TQObject* parent=0,const char * name=0); /** * Delete the sprite cache **/ ~KSpriteCache(); /** * Change the grafichs directory. * * @todo this does not flush the cache or so... **/ bool setGrafixDir(TQString dir); // dir and load config /** * Change the name of the config file. Its default is grafix.rc **/ void setRcFile(TQString file); /** * return the graphics directory **/ TQString grafixDir() {return mGrafixDir;} /** * return the rc/configuration file **/ TQString rcFile() {return mRcFile;} /** * returns the canvas which belongs to the cache **/ TQCanvas *canvas() const {return mCanvas;} /** * sets the canvas belonging to the cache * * @todo could be done in the constructor **/ void setCanvas(TQCanvas *c) {mCanvas=c;} /** * returns the @ref TDEConfig configuration file where thegraphical data is * read. Access to this is necessary if you want to store general game infos * in theis file to or if you want to read additional sprite data which are * not read be the default functions. **/ TDEConfig *config() {return mConfig;} /** * Main function to create a sprite. You call this like *
  * KSprite *sprite=(KSprite *)(yourcahce->getItem("hello",1));
  * if (sprite) sprite->show();
  * 
* Calling this function will load the given sprite from the * configuration file. Its type is determined by the rtti= entry * of the section [hello] in that file. Default is a KSprite. * This file defines all data of the sprite so that you just have to show it. * Each copy of the sprite gets its own number (1,2,...) * Note: The sprite is hidden upon creation and you need to show it * explicitly. * TODO: What definitions are possible in the rc file * * @param name - the name of the sprite resp. the secion in the rc file * @param no - the unique number of the sprite * @return sprite - returns the sprite pointer as @ref TQCanvasItem * * @todo support call without number argument as single sprite's * @todo support loading of frame sequence via one big pixmap * **/ TQCanvasItem *getItem(TQString name, int no); /** * This function loads a pixmap from the given file. Optional you can also * provide a mask file. Also optinal you can provide the directory. Default * is the directory which is set with this @ref KSpriteCache **/ TQPixmap * loadPixmap(TQString file,TQString mask=TQString(),TQString dir=TQString()); /** * Deletes a item form the sprite cache given as a pointer to it **/ void deleteItem(TQCanvasItem *item); /** * Same as above but delete the item with the name and number **/ void deleteItem(TQString s,int no); /** * Deletes all items in the cache **/ void deleteAllItems(); protected: /** * Loads the default properties for all TQCanvasItems from the given config * file. This is at the moment *
  * x=(double)
  * y=(double)
  * z=(double)
  * 
**/ void configureCanvasItem(TDEConfig *config,TQCanvasItem *item); /** * Copies the default properties for all TQCanvasItems from another sprite. * Same as above. **/ void configureCanvasItem(TQCanvasItem *original,TQCanvasItem *item); /** * Loads an item with the given name form the given config file. From the * rtti entry it is determined what type it is and then it is loaded. **/ virtual TQCanvasItem *loadItem(TDEConfig *config,TQString name); /** * Clone the sprite from another sprite, mostly from the copy stored in the * cache. **/ virtual TQCanvasItem *cloneItem(TQCanvasItem *original); /** * Creates a pixmap array for a @ref KSprite from the given config file * for the sprite with the given name (is the name necessary?). * Parameters are *
  *   offset=(TQPoint)       : The sprites offset (where 0,0 is)
  *   pixmaps=(TQStringList) : List of operations to create frames (TODO *   rename)
  *                           if ommited one operation without name is used
  * 
* All following calls have to be preceded by every given string of the * pixmaps section. If this section is not supplied they can be used without * prefix but only one frame sequence is created. *
  *   method=(TQString)  : load, scale (default=load)
  *                       load: loads number frames from file
  *                       scale: scales  number frames from one loaded file
  *   number=(int)      : how many frames to generate
  *   file=(Qstring)    : the filename to load (can contain printf format args
  *                       as %d which are replaced, e.g. file=hello_%d.png
  *   mask=(TQString)    : Same for the mask of the pixmaps
  *   axis=(int)        : (scale only): scale axis (1=x,2=y,3=x+y)
  *   final=(double)    : final scale in percent (default 0.0, i.e. complete scaling)
  *   colorfilter=1,h,s,v: make a HSV transform of all sprite images
  *   colorfilter=2     :  make it gray (lighter=100 is default)
  *   colorfilter=2,g   : make it gray and lighter (positiv) or darker (negative)
  * 
**/ virtual TQCanvasPixmapArray *createPixmapArray(TDEConfig *config,TQString name); /** * Reads the animations from the config file and calls the corresponding * KSprite function to create them. *
  *  anim0=a,b,c,d
  *  anim1=e,f,g,h
  * 
* Where the animations have to to be in sequence starting with 0 (i.e. * anim0). a is the first frame of the animation. b is * the last frame of the animation. c is the mode of the animations, * see @ref KSprite::createAnimation and d is the delay in cycles * of the qcanvas animnation. * * @param config - the config file the sprite is read from * @param sprite - the sprite whose animations are set **/ void createAnimations(TDEConfig *config,KSprite *sprite); /** * Same as above but to copy the animations from an existing sprite **/ void createAnimations(KSprite *original,KSprite *sprite); /** * Change a pixmap to grey values. If the second argument is bigger * than 100 the pixmap is made lighter and if it less then 100 it is * made darker too **/ virtual void changeGrey(TQPixmap *pixmap,int lighter=100); /** * Change the HAS value of the pixmap by dH, dS and dV **/ virtual void changeHSV(TQPixmap *pixmap,int dh,int ds,int dv); /** * Apply the filters as defined in the config file to the sprite name * (TODO is this argument needed) to the pixmap. */ virtual void applyFilter(TQPixmap *pixmap,TDEConfig *config,TQString name); /** * resets the cache (?) */ void reset(); protected: TQDict mItemDict; // Spritename lookup TQDict mCloneDict; // clone Items lookup TQString mGrafixDir; TQString mRcFile; TDEConfig *mConfig; TQCanvas *mCanvas; }; #endif