|
|
|
/***************************************************************************
|
|
|
|
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 <tqcanvas.h>
|
|
|
|
#include <tqdict.h>
|
|
|
|
|
|
|
|
class KConfig;
|
|
|
|
|
|
|
|
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
|
|
|
|
TQ_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 KDE game object
|
|
|
|
* @author Martin Heni <martin@heni-online.de>
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
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:
|
|
|
|
* <pre>
|
|
|
|
* connect(sprite->createNotify(),TQT_SIGNAL(signalNotify(TQCanvasItem *,int)),
|
|
|
|
* this,TQT_SLOT(moveDone(TQCanvasItem *,int)));
|
|
|
|
* </pre>
|
|
|
|
* 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 KConfig 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:
|
|
|
|
* <pre>
|
|
|
|
* # 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
|
|
|
|
*
|
|
|
|
* </pre>
|
|
|
|
*
|
|
|
|
* @todo Support single sprites (only one copy in memory)
|
|
|
|
* Support more sprite types (currently KSprite and TQCanvasText)
|
|
|
|
*
|
|
|
|
* @short The main KDE game object
|
|
|
|
* @author Martin Heni <martin@heni-online.de>
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
class KSpriteCache : public TQObject
|
|
|
|
{
|
|
|
|
Q_OBJECT
|
|
|
|
TQ_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 <em>grafix.rc</em>
|
|
|
|
**/
|
|
|
|
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 KConfig 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.
|
|
|
|
**/
|
|
|
|
KConfig *config() {return mConfig;}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Main function to create a sprite. You call this like
|
|
|
|
* <pre>
|
|
|
|
* KSprite *sprite=(KSprite *)(yourcahce->getItem("hello",1));
|
|
|
|
* if (sprite) sprite->show();
|
|
|
|
* </pre>
|
|
|
|
* 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
|
|
|
|
* <pre>
|
|
|
|
* x=(double)
|
|
|
|
* y=(double)
|
|
|
|
* z=(double)
|
|
|
|
* </pre>
|
|
|
|
**/
|
|
|
|
void configureCanvasItem(KConfig *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(KConfig *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
|
|
|
|
* <pre>
|
|
|
|
* 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
|
|
|
|
* </pre>
|
|
|
|
* 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.
|
|
|
|
* <pre>
|
|
|
|
* 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)
|
|
|
|
* </pre>
|
|
|
|
**/
|
|
|
|
virtual TQCanvasPixmapArray *createPixmapArray(KConfig *config,TQString name);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Reads the animations from the config file and calls the corresponding
|
|
|
|
* KSprite function to create them.
|
|
|
|
* <pre>
|
|
|
|
* anim0=a,b,c,d
|
|
|
|
* anim1=e,f,g,h
|
|
|
|
* </pre>
|
|
|
|
* Where the animations have to to be in sequence starting with 0 (i.e.
|
|
|
|
* anim0). <em>a</em> is the first frame of the animation. <em>b</em> is
|
|
|
|
* the last frame of the animation. <em>c</em> is the mode of the animations,
|
|
|
|
* see @ref KSprite::createAnimation and <em>d</em> 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(KConfig *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,KConfig *config,TQString name);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* resets the cache (?)
|
|
|
|
*/
|
|
|
|
void reset();
|
|
|
|
|
|
|
|
protected:
|
|
|
|
TQDict<TQCanvasItem> mItemDict; // Spritename lookup
|
|
|
|
TQDict<TQCanvasItem> mCloneDict; // clone Items lookup
|
|
|
|
|
|
|
|
TQString mGrafixDir;
|
|
|
|
TQString mRcFile;
|
|
|
|
KConfig *mConfig;
|
|
|
|
TQCanvas *mCanvas;
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
#endif
|