1 /* This file is part of KsirK. 2 Copyright (C) 2001-2007 Gael de Chalendar <kleag@free.fr> 3 4 KsirK is free software; you can redistribute it and/or 5 modify it under the terms of the GNU General Public 6 License as published by the Free Software Foundation, either version 2 7 of the License, or (at your option) any later version. 8 9 This program is distributed in the hope that it will be useful, 10 but WITHOUT ANY WARRANTY; without even the implied warranty of 11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 General Public License for more details. 13 14 You should have received a copy of the GNU General Public License 15 along with this program; if not, write to the Free Software 16 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 17 02110-1301, USA 18 */ 19 20 /* begin : Wed Jul 18 2001 */ 21 22 23 #ifndef ANIMSPRITE_H 24 #define ANIMSPRITE_H 25 26 #include "KsirkGlobalDefinitions.h" 27 #include "animspritespool.h" 28 29 #include <QGraphicsItem> 30 #include <QTimer> 31 32 #include <limits> 33 #include <QTextStream> 34 35 class QSvgRenderer; 36 37 namespace Ksirk 38 { 39 40 class BackGnd; 41 namespace GameLogic 42 { 43 class Country; 44 } 45 46 /** 47 * The AnimSprite objects are the animated images used for all individual 48 * moving objects in KsirK. It is based on QGraphicsPixmapItem that handle 49 * all sprite specific behavior (sequence of images...). The individual 50 * images are taken from an SVG image that stores all the versions of the sprite. 51 * A sprite also have a direction (that allows to select the images looking 52 * toward left or right) and a destination point allowing to handle sprite 53 * movement. 54 * 55 */ 56 class AnimSprite : public QObject, public QGraphicsPixmapItem 57 { 58 Q_OBJECT 59 public: 60 /** 61 * When used for fight display, the sprites can be attacker or 62 * defendant. In the other cases, they are nothing particular (NONE) 63 * This state is only used for explosion animation 64 */ 65 enum State {NONE, ATTACKER, DEFENDANT}; 66 67 enum TDir {state, right, left, up, down, N, S, E, O, NO, SO, SE, NE}; 68 69 /** 70 * This constructor allows to create a new @ref AnimSprite whose images are 71 * taken from the given file name with the given number of frames and 72 * number of look directions 73 * @param svgid The id of the SVG element from which to load images 74 * @param aBackGnd The background giving info about the world geometry and 75 * access to the underlying QGraphicsScene 76 * @param nbFrames The number of different frames in this sprite animation, 77 * thus the number of columns in the sprite image 78 * @param nbDirs The number of different views on the sprite, 79 * thus the number of rows in the sprite image 80 * @param visibility Measures how much this sprite is visible. It gives its 81 * Z value on the graphics scene. 82 */ 83 AnimSprite(const QString &svgid, 84 unsigned int width, 85 unsigned int height, 86 unsigned int nbFrames, unsigned int nbDirs, 87 double zoom, 88 BackGnd* aBackGnd, 89 unsigned int visibility = 100); 90 91 /** The default destructor */ 92 ~AnimSprite() override; 93 94 /** 95 * Moves the sprite by one step towards its destinationPoint. 96 */ 97 void moveIt(); 98 99 /** 100 * Hides and shows the sprite. Causes it to be repainted. 101 */ 102 void repaint(); 103 104 /** 105 * Return true if the current frame is the last one. False otherwise. 106 */ 107 bool isLastFrame() const; 108 109 //@{ 110 /** 111 * Accessors to some variables 112 */ 113 void setDestination(GameLogic::Country *); 114 GameLogic::Country *getDestination(); 115 void setDestinationPoint(const QPointF &); 116 const QPointF& getDestinationPoint() const; 117 bool isAttacker() const; 118 void setAttacker(); 119 bool isDefendant() const; 120 void setDefendant(); 121 bool isNone() const; 122 void setNone(); getBackGnd()123 inline BackGnd* getBackGnd() {return backGnd;} 124 //@} 125 126 /** 127 * Bit to bit comparison 128 */ 129 int operator==(const AnimSprite& Arg1) const; 130 131 /** 132 * executes setLook towards left or right according to the relative 133 * abscissa of the current position point and the destination point 134 */ 135 void turnTowardDestination(); 136 137 /** 138 * Simplified changing of the images sequence of the sprite. Use default 139 * values built from the given id 140 * @param id The base id from which skin data is accessed 141 */ 142 void changeSequence(const QString &id); 143 144 /** 145 * Change the images sequence of the sprite. 146 * @param imgPath The path to the SVG file containing the sprite's new images 147 * @param newNbFrames The number of frames of the sprite in the new image 148 * @param nbDirs The number of directions of the sprite in the new image 149 */ 150 void changeSequence(const QString &imgPath, 151 unsigned int width, 152 unsigned int height, 153 unsigned int newNbFrames, unsigned int nbDirs); 154 155 /** Turns the sprite towards left */ 156 void setLookLeft(); 157 158 /** Turns the sprite towards right */ 159 void setLookRight(); 160 161 /** 162 * Test if the sprites looks to left 163 * @return true if the sprite is directed towards left and false otherwise 164 */ 165 bool looksToLeft() const; 166 167 /** 168 * Test if the sprites looks to right 169 * @return true if the sprite is directed towards right and true otherwise 170 */ 171 bool looksToRight() const; 172 173 /** Write property of bool approachDestByRight. */ 174 void setApproachDestByRight( const bool& _newVal); 175 /** Read property of bool approachDestByRight. */ 176 bool getApproachDestByRight() const; 177 178 /** Write property of bool approachDestByLeft . */ 179 void setApproachDestByLeft ( const bool& _newVal); 180 /** Read property of bool approachDestByLeft . */ 181 bool getApproachDestByLeft () const; 182 183 /** Write property of bool approachDestByTop. */ 184 void setApproachDestByTop( const bool& _newVal); 185 /** Read property of bool approachDestByTop. */ 186 bool getApproachDestByTop() const; 187 188 /** Write property of bool approachDestByBottom . */ 189 void setApproachDestByBottom ( const bool& _newVal); 190 /** Read property of bool approachDestByBottom . */ 191 bool getApproachDestByBottom () const; 192 193 /** 194 * Return the maximum value for x for this sprite by looking to its 195 * including background. Necessary for directed approaches. 196 */ 197 qreal getMaxX() const; 198 199 /** 200 * Return the maximum value for y for this sprite by looking to its 201 * including background. Necessary for directed approaches. 202 */ 203 qreal getMaxY() const; 204 205 /** returns the current state of the sprite */ 206 State getState() const; 207 208 /** Return true if the state of the game is the argument; false otherwise */ 209 bool isMyState(State state) const; 210 211 /** sets the new state of the game */ 212 void setState(State newState); 213 214 /** 215 * This function chooses the approach mode of a sprite towards its destination: 216 * if the distance between the origin and the destination is higher than half 217 * the size of the map and if the origin and destination countries comunicate, 218 * then the sprite should choose an approach by left or right, through the 219 * edge of the map. 220 * This protected method will be called by three public functions specialized 221 * using as source point, respectivly, the infantryman point, the cavalryman 222 * point and the cannon point. 223 */ 224 void setupTravel(GameLogic::Country* src, GameLogic::Country* dest, 225 const QPointF& srcPoint, const QPointF& destPoint); 226 227 /** 228 * This virtual function chooses the approach mode of a sprite towards its 229 * destination. It will be overloaded by subclasses: 230 * if the distance between the origin and the destination is higher than half 231 * the size of the map and if the origin and destination countries comunicate, 232 * then the sprite should choose an approach by left or right, through the 233 * edge of the map. 234 */ 235 virtual void setupTravel(GameLogic::Country* src, GameLogic::Country* dest, 236 const QPointF* dpi=0); 237 238 /** 239 * Saves a XML representation of the sprite for game saving purpose 240 * @param xmlStream The stream to write on 241 */ 242 virtual void saveXml(QTextStream& xmlStream); 243 244 /** 245 * Retrieves the numFrame's frame image of this sprite in its current 246 * direction 247 * @param numFrame The index of the image to retrieve 248 * @return a copy of the numFrame's image of this sprite in its current 249 * direction 250 */ 251 QPixmap image(unsigned int numFrame) const; 252 253 void arrival(); 254 255 void setAnimated(unsigned int numberOfShots = std::numeric_limits<unsigned int>::max()); 256 257 void setStatic(); 258 259 void applyZoomFactor(qreal zoomFactor); 260 261 void addDecoration(const QString& svgid, const QRectF& geometry); 262 263 public slots: 264 void animate(); 265 266 signals: 267 268 /** 269 * emitted when the coordinates of the sprite become equal to those of its 270 * destination point 271 */ 272 void atDestination(AnimSprite* sprite); 273 274 void animationFinished(AnimSprite* sprite); 275 276 protected: sceneEvent(QEvent *)277 bool sceneEvent ( QEvent * ) override {return false;} 278 279 /** 280 * Set this sprite to display its numFrame's frame. If numFrame is greater 281 * than the number of frames of the sprite, do nothing 282 * @param numFrame The number of the frame to display 283 */ 284 void setFrame(unsigned int numFrame); 285 286 /** 287 * Builds the sequence of images of this sprite using the SVG renderer and 288 * data about zoom factor, look direction, etc. 289 */ 290 void sequenceConstruction(); 291 292 /** 293 * changes the direction of this sprite's look 294 */ 295 void setLook(TDir); 296 297 bool m_animated; 298 299 /** 300 * Zoom factor 301 */ 302 double m_zoom; 303 304 private: 305 QString m_svgid; 306 307 /** 308 * Change the active frame to the next one in the list. Use the first one 309 * if the current frame was the last one 310 * 311 */ 312 void nextFrame(); 313 314 /** 315 * Direction of the look of the sprite (left or right) ; 316 * Allows to select the good image sequence 317 */ 318 TDir look; 319 320 /** 321 * The number of versions of the sprite 322 */ 323 unsigned int nbVersions; 324 325 /** 326 * The background onto which the sprite will be displayed 327 */ 328 BackGnd *backGnd; 329 330 /** 331 * For a sprite moving from one country to another, the destination one ; 332 * NULL otherwise. 333 */ 334 GameLogic::Country *destination; 335 336 /** 337 * The coordinates of the destination (gun point or flag point for example) 338 */ 339 QPointF destinationPoint; 340 341 /** 342 * the number of images in a version of the sprite 343 */ 344 unsigned int frames; 345 346 /** 347 * the number of the current image in the current version of the sprite 348 */ 349 unsigned int actFrame; 350 351 /** 352 * The attacking state of the sprite 353 */ 354 State myState; 355 356 /** 357 * Position information needed to load graphics from the pool 358 */ 359 double m_height, m_width; 360 361 /** If this member is true, the sprite should approach its destination by 362 * the left. So, if it is at the right side of its dest, it will continue 363 * towards right up to the right side of the world. There, it will jump at 364 * the left side and continue directly towards its destination. 365 * When this member is set to true, the sprite should set 366 * approachDestByRight to false. If both are false, the sprite will go 367 * directly towards its destination. 368 */ 369 bool approachDestByLeft ; 370 371 /** If this member is true, the sprite should approach its destination by 372 * the right. So, if it is at the left side of its dest, it will continue 373 * towards left up to the left side of the world. There, it will jump at 374 * the right side and continue directly towards its destination. 375 * When this member is set to true, the sprite should set 376 * approachDestByLeft to false. If both are false, the sprite will go 377 * directly towards its destination. 378 */ 379 bool approachDestByRight; 380 381 /** If this member is true, the sprite should approach its destination by 382 * the top. So, if it is under its dest, it will continue 383 * towards the bottom down to the bottom side of the world. There, it will 384 * jump at the top side and continue directly towards its destination. 385 * When this member is set to true, the sprite should set 386 * approachDestByBottom to false. If both are false, the sprite will go 387 * directly towards its destination. 388 */ 389 bool approachDestByTop ; 390 391 /** If this member is true, the sprite should approach its destination by 392 * the bottom. So, if it is upper its dest, it will continue 393 * towards the top up to the top side of the world. There, it will jump at 394 * the bottom side and continue directly towards its destination. 395 * When this member is set to true, the sprite should set 396 * approachDestByTop to false. If both are false, the sprite will go 397 * directly towards its destination. 398 */ 399 bool approachDestByBottom; 400 401 402 /** 403 * Stores the images of this sprite for all its directions with the current 404 * SVG file and zoom factor. 405 */ 406 QList<QPixmap> m_frames; 407 408 /** 409 * This SVG renderer stores the SVG file of this sprite, renders it at the 410 * desired zoom factor and the result is used to fill the frames list 411 */ 412 QSvgRenderer* m_renderer; 413 414 unsigned int m_numberOfShots; 415 416 QTimer m_timer; 417 418 QString m_skin; 419 }; 420 421 } // closing namespace Ksirk 422 423 #endif // ANIMSPRITE_H 424