This is the verbatim text of the QwSpriteField.h include file.
// QwSpriteField and associated classes, using Qt C++ class library.
// class QwSpriteField
// class QwImageSpriteField : public QwSpriteField
// class QwSpriteFieldView : public QWidget
//
// class QwSpriteFieldGraphic
// class QwVirtualSprite : public QwSpriteFieldGraphic
// class QwSprite : public QwVirtualSprite
//
// class QwSpritePixmap : public QPixmap
// class QwSpritePixmapSequence
//
// Author: Warwick Allison (warwick@cs.uq.edu.au)
// Date: 26/03/96
// Copyright (C) 1995-96 by Warwick Allison.
//
#ifndef QwSpriteField_H
#define QwSpriteField_H
#include <Pix.h> // GNU libg++ `Pix' concept (it's just a void*).
#include <qbitmap.h>
#include <qwidget.h>
#include <qlist.h>
class QwSprite;
class QwSpriteFieldGraphic;
class QwChunkRec;
class QwSpriteField;
class QwSpriteFieldView : public QWidget
{
public:
QwSpriteFieldView(QwSpriteField* viewing=0, QWidget* parent=0, const char* name=0, WFlags f=0);
~QwSpriteFieldView();
void view(QwSpriteField*);
virtual QRect viewArea() const;
protected:
// Cause Update for this widget
virtual void paintEvent(QPaintEvent *);
private:
QwSpriteField* viewing;
};
class QwSpriteField
{
public:
QwSpriteField(int w, int h, int chunksize=16, int maxclusters=20);
virtual ~QwSpriteField();
// Call this after some amount of QwSpriteFieldGraphic motion.
void update();
void resize(int width, int height);
int width() const { return awidth; }
int height() const { return aheight; }
int chunkSize() const { return chunksize; }
// (x,y) is *world* position, (i,j) is chunk coordinate.
Pix topAt(int x, int y);
Pix lookIn(int x, int y, int w, int h);
void next(Pix&);
void end(Pix& p); // need not be called for p==0
QwSpriteFieldGraphic* at(Pix p) const;
bool exact(Pix p) const; // Pre: (p && At(p))
void protectFromChange(Pix p);
bool sameChunk(int x1, int y1, int x2, int y2) const
{ return x1/chunksize==x2/chunksize && y1/chunksize==y2/chunksize; }
void setChangedChunk(int i, int j);
void setChangedChunkContaining(int x, int y);
// These call setChangedChunk
void addGraphicToChunk(QwSpriteFieldGraphic*, int i, int j);
void removeGraphicFromChunk(QwSpriteFieldGraphic*, int i, int j);
void addGraphicToChunkContaining(QwSpriteFieldGraphic*, int x, int y);
void removeGraphicFromChunkContaining(QwSpriteFieldGraphic*, int x, int y);
// This is internal.
void* listAtChunkTopFirst(int i, int j);
static void setPositionPrecision(int downshifts) { posprec=downshifts; }
static int positionPrecision() { return posprec; }
static int world_to_x(int i) { return i>>posprec; }
static int x_to_world(int i) { return i<<posprec; }
// These are for QwSpriteFieldView to use
void addView(QwSpriteFieldView*);
void removeView(QwSpriteFieldView*);
void updateInView(QwSpriteFieldView*, const QRect&); // pre: view has been added
protected:
virtual void drawBackground(QPainter&, const QRect& area);
virtual void drawForeground(QPainter&, const QRect& area);
void forceRedraw(const QRect&);
private:
QwChunkRec& chunk(int i, int j);
QwChunkRec& chunkContaining(int x, int y);
void drawArea(const QRect&, bool only_changes, QwSpriteFieldView* one_view);
int awidth,aheight;
const int chunksize;
const int maxclusters;
int chwidth,chheight;
QwChunkRec* chunks;
QList<QwSpriteFieldView> viewList;
static unsigned int posprec;
};
class QwSpritePixmap : public QPixmap
{
public:
QwSpritePixmap(const char* datafilename, const char* maskfilename);
~QwSpritePixmap();
private:
friend class QwVirtualSprite;
friend class QwSpritePixmapSequence;
friend class QwSpriteFieldIterator;
int hotx,hoty;
QImage* collision_mask;
int colw,colh;
int colhotx,colhoty;
QBitmap mask;
};
class QwImageSpriteField : public QwSpriteField
{
public:
QwImageSpriteField(const char* imagefile, int w, int h, int chunksize=16, int maxclusters=20);
virtual ~QwImageSpriteField();
protected:
virtual void drawBackground(QPainter&, const QRect& area);
private:
QPixmap image;
};
class QwSpriteFieldGraphic
{
public:
static void setCurrentSpriteField(QwSpriteField*);
// Alternatively, Graphics can be individually placed on QwSpriteFields.
void setSpriteField(QwSpriteField*);
QwSpriteFieldGraphic();
virtual int z() const=0;
virtual void draw(QPainter&)=0;
void show();
void hide();
void visible(bool yes);
bool visible() const; // initially true for QwSpriteFieldGraphics
// true iff the graphic includes the given pixel position.
virtual bool at(int x, int y) const=0;
// true iff the graphic intersects with the given area.
virtual bool at(const QRect& rect) const=0;
// true iff the graphic intersects with the given bitmap.
// rect gives the offset of the bitmap and relevant area.
// The default is to just call At(const QRect& rect) above.
virtual bool at(const QImage* image, const QRect& rect) const;
virtual int rtti() const;
protected:
QwSpriteField* playfield;
// Visible() will always be true when this is called, as it will
// be changed before the call when showing and after when hiding.
// Note, may also be called while moving between QwSpriteFields
// (see SetSpriteField), such that the QwSpriteFieldGraphic is not visible when
// moved (conceptually, invisibility is not being on any QwSpriteField).
virtual void makeVisible(bool yes);
static int world_to_x(int i) { return QwSpriteField::world_to_x(i); }
static int x_to_world(int i) { return QwSpriteField::x_to_world(i); }
private:
static QwSpriteField* current_playfield;
bool vis;
};
class QwSpritePixmapSequence
{
public:
QwSpritePixmapSequence(const char* datafilenamepattern,
const char* maskfilenamepattern, int framecount=1);
void readCollisionMasks(const char* filenamepattern);
int operator!(); // Failure check.
QwSpritePixmap* image(int i) const { return img[i]; }
int frameCount() const { return framecount; }
private:
int framecount;
QwSpritePixmap** img;
};
class QwVirtualSprite : public QwSpriteFieldGraphic
{
public:
QwVirtualSprite();
virtual ~QwVirtualSprite();
// Reduce collision precision by right-shifting effective coordinates.
// by the given amount. Negative values can be used, in which case
// the resolution is increased (not often useful). (default==0)
//
static void setPixelCollisionPrecision(int downshifts);
int width() const;
int height() const;
int colWidth() const;
int colHeight() const;
// These components must be provided by concrete subclasses.
// Note the usage of AddToChunks and RemoveFromChunks protected methods.
//
virtual QwSpritePixmap* image() const=0;
virtual int x() const=0;
virtual int y() const=0;
virtual bool at(int x, int y) const;
virtual bool at(const QRect& rect) const;
virtual bool at(const QImage* image, const QRect& rect) const;
virtual int rtti() const;
// Traverse intersecting Graphics.
//
// See QwSpriteField::TopAt() for more details.
//
Pix neighbourhood();
Pix neighbourhood(int nx, int ny);
Pix neighbourhood(int nx, int ny, QwSpritePixmap*);
//
void next(Pix&);
void end(Pix& p); // need not be called for p==0
QwSpriteFieldGraphic* at(Pix p) const;
bool exact(Pix p) const; // Pre: (p && At(p))
bool hitting(QwSpriteFieldGraphic&) const;
bool wouldHit(QwSpriteFieldGraphic&, int x, int y, QwSpritePixmap*) const;
static int world_to_col(int i) { return i>>colprec; }
static int col_to_world(int i) { return i<<colprec; }
protected:
virtual void makeVisible(bool yes);
virtual void draw(QPainter&);
// Call these either side of X(), Y(), or Image() value changes.
void addToChunks();
void removeFromChunks();
int absX() const;
int absY() const;
int absX2() const;
int absY2() const;
int absColX() const;
int absColY() const;
int absColX2() const;
int absColY2() const;
private:
static unsigned int colprec;
};
template<class COORD>
class QwPositionedSprite : public QwVirtualSprite
{
public:
QwPositionedSprite(QwSpritePixmapSequence&);
QwPositionedSprite();
void setSequence(QwSpritePixmapSequence& seq);
virtual ~QwPositionedSprite();
void frame(int);
int frame() const { return frm; }
int frameCount() const { return images->frameCount(); }
virtual int x() const { return (int)myx; }
virtual int y() const { return (int)myy; }
COORD exact_x() const { return myx; }
COORD exact_y() const { return myy; }
void x(COORD);
void y(COORD);
void moveBy(COORD dx, COORD dy);
void moveTo(COORD x, COORD y);
virtual void moveTo(COORD x, COORD y, int frame);
virtual int z() const { return alt; }
void z(int a) { alt=a; changeChunks(); }
virtual int rtti() const;
Pix neighbourhood(int frame); // Neighbourhood if Frame(frame).
Pix neighbourhood(COORD nx, COORD ny, int frame); // Both of above.
bool wouldHit(QwSpriteFieldGraphic&, COORD x, COORD y, int frame) const;
private:
COORD myx,myy;
int frm;
int alt;
void changeChunks();
virtual QwSpritePixmap* image() const { return images->image(frm); }
QwSpritePixmap* image(int f) const { return images->image(f); }
QwSpritePixmapSequence* images;
};
template <class COORD>
class QwMobilePositionedSprite : public QwPositionedSprite<COORD> {
public:
QwMobilePositionedSprite(QwSpritePixmapSequence&);
QwMobilePositionedSprite();
void bounds(COORD left, COORD top, COORD right, COORD bottom);
void adoptPlayfieldBounds();
static const int Ignore=0;
static const int Stop=1;
static const int Wrap=2;
static const int Bounce=3;
void setBoundsAction(int action);
bool outOfBounds();
void setVelocity(COORD dX, COORD dY) { dx=dX; dy=dY; }
void forward(COORD multiplier);
void forward(COORD multiplier, int frame);
virtual void moveTo(COORD x, COORD y, int frame);
private:
int bounds_action;
COORD dx,dy;
COORD b_left, b_top, b_right, b_bottom;
};
// The most common instantiations of the above templates...
class QwSprite : public QwPositionedSprite<int> {
public:
QwSprite(QwSpritePixmapSequence& s) : QwPositionedSprite<int>(s) { }
QwSprite() : QwPositionedSprite<int>() { }
};
class QwRealSprite : public QwPositionedSprite<double> {
public:
QwRealSprite(QwSpritePixmapSequence& s) : QwPositionedSprite<double>(s) { }
QwRealSprite() : QwPositionedSprite<double>() { }
};
class QwMobileSprite : public QwMobilePositionedSprite<int> {
public:
QwMobileSprite(QwSpritePixmapSequence& s) : QwMobilePositionedSprite<int>(s) { }
QwMobileSprite() : QwMobilePositionedSprite<int>() { }
};
class QwRealMobileSprite : public QwMobilePositionedSprite<double> {
public:
QwRealMobileSprite(QwSpritePixmapSequence& s) : QwMobilePositionedSprite<double>(s) { }
QwRealMobileSprite() : QwMobilePositionedSprite<double>() { }
};
#endif