File indexing completed on 2025-04-20 03:48:07
0001 /* This file is part of KsirK. 0002 Copyright (C) 2001-2007 Gael de Chalendar <kleag@free.fr> 0003 0004 KsirK is free software; you can redistribute it and/or 0005 modify it under the terms of the GNU General Public 0006 License as published by the Free Software Foundation, either version 2 0007 of the License, or (at your option) any later version. 0008 0009 This program is distributed in the hope that it will be useful, 0010 but WITHOUT ANY WARRANTY; without even the implied warranty of 0011 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 0012 General Public License for more details. 0013 0014 You should have received a copy of the GNU General Public License 0015 along with this program; if not, write to the Free Software 0016 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 0017 02110-1301, USA 0018 */ 0019 0020 /* begin : Wed Jul 18 2001 */ 0021 0022 0023 #ifndef ANIMSPRITE_H 0024 #define ANIMSPRITE_H 0025 0026 #include "KsirkGlobalDefinitions.h" 0027 #include "animspritespool.h" 0028 0029 #include <QGraphicsItem> 0030 #include <QPixmap> 0031 #include <QTimer> 0032 0033 #include <limits> 0034 #include <QTextStream> 0035 0036 class QSvgRenderer; 0037 0038 namespace Ksirk 0039 { 0040 0041 class BackGnd; 0042 namespace GameLogic 0043 { 0044 class Country; 0045 } 0046 0047 /** 0048 * The AnimSprite objects are the animated images used for all individual 0049 * moving objects in KsirK. It is based on QGraphicsPixmapItem that handle 0050 * all sprite specific behavior (sequence of images...). The individual 0051 * images are taken from an SVG image that stores all the versions of the sprite. 0052 * A sprite also have a direction (that allows to select the images looking 0053 * toward left or right) and a destination point allowing to handle sprite 0054 * movement. 0055 * 0056 */ 0057 class AnimSprite : public QObject, public QGraphicsPixmapItem 0058 { 0059 Q_OBJECT 0060 public: 0061 /** 0062 * When used for fight display, the sprites can be attacker or 0063 * defendant. In the other cases, they are nothing particular (NONE) 0064 * This state is only used for explosion animation 0065 */ 0066 enum State {NONE, ATTACKER, DEFENDANT}; 0067 0068 enum TDir {state, right, left, up, down, N, S, E, O, NO, SO, SE, NE}; 0069 0070 /** 0071 * This constructor allows to create a new @ref AnimSprite whose images are 0072 * taken from the given file name with the given number of frames and 0073 * number of look directions 0074 * @param svgid The id of the SVG element from which to load images 0075 * @param aBackGnd The background giving info about the world geometry and 0076 * access to the underlying QGraphicsScene 0077 * @param nbFrames The number of different frames in this sprite animation, 0078 * thus the number of columns in the sprite image 0079 * @param nbDirs The number of different views on the sprite, 0080 * thus the number of rows in the sprite image 0081 * @param visibility Measures how much this sprite is visible. It gives its 0082 * Z value on the graphics scene. 0083 */ 0084 AnimSprite(const QString &svgid, 0085 unsigned int width, 0086 unsigned int height, 0087 unsigned int nbFrames, unsigned int nbDirs, 0088 double zoom, 0089 BackGnd* aBackGnd, 0090 unsigned int visibility = 100); 0091 0092 /** The default destructor */ 0093 ~AnimSprite() override; 0094 0095 /** 0096 * Moves the sprite by one step towards its destinationPoint. 0097 */ 0098 void moveIt(); 0099 0100 /** 0101 * Hides and shows the sprite. Causes it to be repainted. 0102 */ 0103 void repaint(); 0104 0105 /** 0106 * Return true if the current frame is the last one. False otherwise. 0107 */ 0108 bool isLastFrame() const; 0109 0110 //@{ 0111 /** 0112 * Accessors to some variables 0113 */ 0114 void setDestination(GameLogic::Country *); 0115 GameLogic::Country *getDestination(); 0116 void setDestinationPoint(const QPointF &); 0117 const QPointF& getDestinationPoint() const; 0118 bool isAttacker() const; 0119 void setAttacker(); 0120 bool isDefendant() const; 0121 void setDefendant(); 0122 bool isNone() const; 0123 void setNone(); 0124 inline BackGnd* getBackGnd() {return backGnd;} 0125 //@} 0126 0127 /** 0128 * Bit to bit comparison 0129 */ 0130 int operator==(const AnimSprite& Arg1) const; 0131 0132 /** 0133 * executes setLook towards left or right according to the relative 0134 * abscissa of the current position point and the destination point 0135 */ 0136 void turnTowardDestination(); 0137 0138 /** 0139 * Simplified changing of the images sequence of the sprite. Use default 0140 * values built from the given id 0141 * @param id The base id from which skin data is accessed 0142 */ 0143 void changeSequence(const QString &id); 0144 0145 /** 0146 * Change the images sequence of the sprite. 0147 * @param imgPath The path to the SVG file containing the sprite's new images 0148 * @param newNbFrames The number of frames of the sprite in the new image 0149 * @param nbDirs The number of directions of the sprite in the new image 0150 */ 0151 void changeSequence(const QString &imgPath, 0152 unsigned int width, 0153 unsigned int height, 0154 unsigned int newNbFrames, unsigned int nbDirs); 0155 0156 /** Turns the sprite towards left */ 0157 void setLookLeft(); 0158 0159 /** Turns the sprite towards right */ 0160 void setLookRight(); 0161 0162 /** 0163 * Test if the sprites looks to left 0164 * @return true if the sprite is directed towards left and false otherwise 0165 */ 0166 bool looksToLeft() const; 0167 0168 /** 0169 * Test if the sprites looks to right 0170 * @return true if the sprite is directed towards right and true otherwise 0171 */ 0172 bool looksToRight() const; 0173 0174 /** Write property of bool approachDestByRight. */ 0175 void setApproachDestByRight( const bool& _newVal); 0176 /** Read property of bool approachDestByRight. */ 0177 bool getApproachDestByRight() const; 0178 0179 /** Write property of bool approachDestByLeft . */ 0180 void setApproachDestByLeft ( const bool& _newVal); 0181 /** Read property of bool approachDestByLeft . */ 0182 bool getApproachDestByLeft () const; 0183 0184 /** Write property of bool approachDestByTop. */ 0185 void setApproachDestByTop( const bool& _newVal); 0186 /** Read property of bool approachDestByTop. */ 0187 bool getApproachDestByTop() const; 0188 0189 /** Write property of bool approachDestByBottom . */ 0190 void setApproachDestByBottom ( const bool& _newVal); 0191 /** Read property of bool approachDestByBottom . */ 0192 bool getApproachDestByBottom () const; 0193 0194 /** 0195 * Return the maximum value for x for this sprite by looking to its 0196 * including background. Necessary for directed approaches. 0197 */ 0198 qreal getMaxX() const; 0199 0200 /** 0201 * Return the maximum value for y for this sprite by looking to its 0202 * including background. Necessary for directed approaches. 0203 */ 0204 qreal getMaxY() const; 0205 0206 /** returns the current state of the sprite */ 0207 State getState() const; 0208 0209 /** Return true if the state of the game is the argument; false otherwise */ 0210 bool isMyState(State state) const; 0211 0212 /** sets the new state of the game */ 0213 void setState(State newState); 0214 0215 /** 0216 * This function chooses the approach mode of a sprite towards its destination: 0217 * if the distance between the origin and the destination is higher than half 0218 * the size of the map and if the origin and destination countries comunicate, 0219 * then the sprite should choose an approach by left or right, through the 0220 * edge of the map. 0221 * This protected method will be called by three public functions specialized 0222 * using as source point, respectivly, the infantryman point, the cavalryman 0223 * point and the cannon point. 0224 */ 0225 void setupTravel(GameLogic::Country* src, GameLogic::Country* dest, 0226 const QPointF& srcPoint, const QPointF& destPoint); 0227 0228 /** 0229 * This virtual function chooses the approach mode of a sprite towards its 0230 * destination. It will be overloaded by subclasses: 0231 * if the distance between the origin and the destination is higher than half 0232 * the size of the map and if the origin and destination countries comunicate, 0233 * then the sprite should choose an approach by left or right, through the 0234 * edge of the map. 0235 */ 0236 virtual void setupTravel(GameLogic::Country* src, GameLogic::Country* dest, 0237 const QPointF* dpi=nullptr); 0238 0239 /** 0240 * Saves a XML representation of the sprite for game saving purpose 0241 * @param xmlStream The stream to write on 0242 */ 0243 virtual void saveXml(QTextStream& xmlStream); 0244 0245 /** 0246 * Retrieves the numFrame's frame image of this sprite in its current 0247 * direction 0248 * @param numFrame The index of the image to retrieve 0249 * @return a copy of the numFrame's image of this sprite in its current 0250 * direction 0251 */ 0252 QPixmap image(unsigned int numFrame) const; 0253 0254 void arrival(); 0255 0256 void setAnimated(unsigned int numberOfShots = std::numeric_limits<unsigned int>::max()); 0257 0258 void setStatic(); 0259 0260 void applyZoomFactor(qreal zoomFactor); 0261 0262 void addDecoration(const QString& svgid, const QRectF& geometry); 0263 0264 public slots: 0265 void animate(); 0266 0267 signals: 0268 0269 /** 0270 * emitted when the coordinates of the sprite become equal to those of its 0271 * destination point 0272 */ 0273 void atDestination(AnimSprite* sprite); 0274 0275 void animationFinished(AnimSprite* sprite); 0276 0277 protected: 0278 bool sceneEvent ( QEvent * ) override {return false;} 0279 0280 /** 0281 * Set this sprite to display its numFrame's frame. If numFrame is greater 0282 * than the number of frames of the sprite, do nothing 0283 * @param numFrame The number of the frame to display 0284 */ 0285 void setFrame(unsigned int numFrame); 0286 0287 /** 0288 * Builds the sequence of images of this sprite using the SVG renderer and 0289 * data about zoom factor, look direction, etc. 0290 */ 0291 void sequenceConstruction(); 0292 0293 /** 0294 * changes the direction of this sprite's look 0295 */ 0296 void setLook(TDir); 0297 0298 bool m_animated; 0299 0300 /** 0301 * Zoom factor 0302 */ 0303 double m_zoom; 0304 0305 private: 0306 QString m_svgid; 0307 0308 /** 0309 * Change the active frame to the next one in the list. Use the first one 0310 * if the current frame was the last one 0311 * 0312 */ 0313 void nextFrame(); 0314 0315 /** 0316 * Direction of the look of the sprite (left or right) ; 0317 * Allows to select the good image sequence 0318 */ 0319 TDir look; 0320 0321 /** 0322 * The number of versions of the sprite 0323 */ 0324 unsigned int nbVersions; 0325 0326 /** 0327 * The background onto which the sprite will be displayed 0328 */ 0329 BackGnd *backGnd; 0330 0331 /** 0332 * For a sprite moving from one country to another, the destination one ; 0333 * NULL otherwise. 0334 */ 0335 GameLogic::Country *destination; 0336 0337 /** 0338 * The coordinates of the destination (gun point or flag point for example) 0339 */ 0340 QPointF destinationPoint; 0341 0342 /** 0343 * the number of images in a version of the sprite 0344 */ 0345 unsigned int frames; 0346 0347 /** 0348 * the number of the current image in the current version of the sprite 0349 */ 0350 unsigned int actFrame; 0351 0352 /** 0353 * The attacking state of the sprite 0354 */ 0355 State myState; 0356 0357 /** 0358 * Position information needed to load graphics from the pool 0359 */ 0360 double m_height, m_width; 0361 0362 /** If this member is true, the sprite should approach its destination by 0363 * the left. So, if it is at the right side of its dest, it will continue 0364 * towards right up to the right side of the world. There, it will jump at 0365 * the left side and continue directly towards its destination. 0366 * When this member is set to true, the sprite should set 0367 * approachDestByRight to false. If both are false, the sprite will go 0368 * directly towards its destination. 0369 */ 0370 bool approachDestByLeft ; 0371 0372 /** If this member is true, the sprite should approach its destination by 0373 * the right. So, if it is at the left side of its dest, it will continue 0374 * towards left up to the left side of the world. There, it will jump at 0375 * the right side and continue directly towards its destination. 0376 * When this member is set to true, the sprite should set 0377 * approachDestByLeft to false. If both are false, the sprite will go 0378 * directly towards its destination. 0379 */ 0380 bool approachDestByRight; 0381 0382 /** If this member is true, the sprite should approach its destination by 0383 * the top. So, if it is under its dest, it will continue 0384 * towards the bottom down to the bottom side of the world. There, it will 0385 * jump at the top side and continue directly towards its destination. 0386 * When this member is set to true, the sprite should set 0387 * approachDestByBottom to false. If both are false, the sprite will go 0388 * directly towards its destination. 0389 */ 0390 bool approachDestByTop ; 0391 0392 /** If this member is true, the sprite should approach its destination by 0393 * the bottom. So, if it is upper its dest, it will continue 0394 * towards the top up to the top side of the world. There, it will jump at 0395 * the bottom side and continue directly towards its destination. 0396 * When this member is set to true, the sprite should set 0397 * approachDestByTop to false. If both are false, the sprite will go 0398 * directly towards its destination. 0399 */ 0400 bool approachDestByBottom; 0401 0402 0403 /** 0404 * Stores the images of this sprite for all its directions with the current 0405 * SVG file and zoom factor. 0406 */ 0407 QList<QPixmap> m_frames; 0408 0409 /** 0410 * This SVG renderer stores the SVG file of this sprite, renders it at the 0411 * desired zoom factor and the result is used to fill the frames list 0412 */ 0413 QSvgRenderer* m_renderer; 0414 0415 unsigned int m_numberOfShots; 0416 0417 QTimer m_timer; 0418 0419 QString m_skin; 0420 }; 0421 0422 } // closing namespace Ksirk 0423 0424 #endif // ANIMSPRITE_H