File indexing completed on 2024-04-21 04:04:45

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 #include "animsprite.h"
0023 #include "skinSpritesData.h"
0024 #include "backgnd.h"
0025 #include "kgamewin.h"
0026 #include "ksirksettings.h"
0027 #include "GameLogic/nationality.h"
0028 #include "GameLogic/country.h"
0029 #include "GameLogic/gameautomaton.h"
0030 #include "GameLogic/onu.h"
0031 
0032 #include <QApplication>
0033 #include <QPoint>
0034 #include <QPixmap>
0035 #include <QPixmapCache>
0036 #include <QSvgRenderer>
0037 
0038 #include <KMessageBox>
0039 #include <KLocalizedString>
0040 #include "ksirk_debug.h"
0041 
0042 namespace Ksirk
0043 {
0044 
0045 using namespace GameLogic;
0046 
0047 AnimSprite::AnimSprite(const QString &svgid,
0048                         unsigned int width,
0049                         unsigned int height,
0050                         unsigned int nbFrames, unsigned int nbDirs,
0051                         double zoom,
0052                         BackGnd* aBackGnd,
0053                         unsigned int visibility) :
0054     QGraphicsPixmapItem(nullptr),
0055     m_animated(false), m_zoom(zoom), m_svgid(svgid),
0056     look(right), nbVersions(nbDirs),
0057     backGnd(aBackGnd), destination(nullptr), destinationPoint(), frames(nbFrames), actFrame(0),
0058     myState(NONE),
0059     m_height(zoom*height),
0060     m_width(zoom*width),
0061     approachDestByLeft(false), approachDestByRight(false),
0062     approachDestByTop(false), approachDestByBottom(false),
0063     m_frames(),
0064     m_renderer(const_cast<ONU*>(aBackGnd->onu())->renderer()),
0065     m_numberOfShots(0),
0066     m_timer(this),
0067     m_skin(backGnd->onu()->skin())
0068 {
0069    aBackGnd-> scene()->addItem(this);
0070 //   qCDebug(KSIRK_LOG) << svgid << nbFrames;
0071   setNone();
0072 
0073   sequenceConstruction();
0074   setZValue(visibility);
0075   show();
0076 
0077   /// @note uncomment here if you want to try sprites animation by connection to a timer
0078 //   connect(GameAutomaton::changeable().game()->frame()->timer(),SIGNAL(timeout()),this,SLOT(animate()));
0079   connect(&m_timer,&QTimer::timeout,this,&AnimSprite::animate);
0080 //   m_timer.setSingleShot(true);
0081   if (frames > 1)
0082   {
0083     m_timer.start(200);
0084   }
0085 }
0086 
0087 AnimSprite::~AnimSprite()
0088 {
0089 //   qCDebug(KSIRK_LOG) << (void*)this ;
0090   m_timer.stop();
0091   disconnect(&m_timer,&QTimer::timeout,this,&AnimSprite::animate);
0092   setStatic();
0093 }
0094 
0095 void AnimSprite::repaint()
0096 {
0097   update();
0098 }
0099 
0100 void AnimSprite::setLook(TDir newLook)
0101 {
0102 //   qCDebug(KSIRK_LOG);
0103   if (newLook != look)
0104   {
0105 //        qCDebug(KSIRK_LOG)<<"setLook : " << newLook << ")";
0106     look=newLook;
0107     setFrame(0);
0108     update();
0109   }
0110 }
0111 
0112 /**
0113  * updates the sequence of images used by the underlying QGraphicsPixmapItem 
0114  * with the ones taken from the image found at imgPath. It is function of the
0115  * direction of the look and the geometry of the sprite
0116  */
0117 void AnimSprite::sequenceConstruction()
0118 {
0119   QList<QPixmap> list;
0120 
0121   const qreal dpr = qApp->devicePixelRatio();
0122   const QSize size((int)(m_width*frames*dpr), (int)(m_height*nbVersions*dpr));
0123 
0124   QPixmap allpm;
0125   QString allpmCacheId = m_skin+m_svgid+QString::number(size.width())+"x"+QString::number(size.height());
0126   if (!QPixmapCache::find(allpmCacheId, &allpm))
0127   {
0128     // Pixmap isn't in the cache, create it and insert to cache
0129     allpm = QPixmap(size);
0130     allpm.fill(Qt::transparent);
0131     QPainter p(&allpm);
0132     m_renderer->render(&p, m_svgid);
0133     allpm.setDevicePixelRatio(dpr);
0134 
0135     QPixmapCache::insert(allpmCacheId, allpm);
0136   }
0137   
0138   const QSize frameSize((int)(m_width * dpr), (int)(m_height * dpr));
0139   for (unsigned int l = 0; l<nbVersions;l++)
0140   {
0141     for (unsigned int i = 0; i<frames;i++)
0142     {
0143 //       qCDebug(KSIRK_LOG)<< "constr s : "<<m_width<<" "<<m_height<<" "<<look-1;
0144       QPixmap pm;
0145       QString pmCacheId = allpmCacheId + QLatin1Char('-') + QString::number(i) + QLatin1Char(':') + QString::number(l);
0146       if (!QPixmapCache::find(pmCacheId, &pm))
0147       {
0148         // Pixmap isn't in the cache, create it and insert to cache
0149         pm = allpm.copy(frameSize.width() * i, frameSize.height() * l,
0150                         frameSize.width(), frameSize.height());
0151         pm.setDevicePixelRatio(dpr);
0152         QPixmapCache::insert(pmCacheId, pm);
0153       }
0154 
0155       list.push_back(pm);
0156     }
0157   }
0158   m_frames = list;
0159 
0160   setFrame(0);
0161 }
0162 
0163 void AnimSprite::changeSequence(const QString &id)
0164 {
0165   qCDebug(KSIRK_LOG) << (void*)this << id;
0166   changeSequence(
0167           id,
0168           Sprites::SkinSpritesData::single().intData(id+"-width"),
0169           Sprites::SkinSpritesData::single().intData(id+"-height"),
0170           Sprites::SkinSpritesData::single().intData(id+"-frames"),
0171           Sprites::SkinSpritesData::single().intData(id+"-versions"));
0172 }
0173 void AnimSprite::changeSequence(const QString &svgid,
0174                                  unsigned int width,
0175                                  unsigned int height,
0176                                  unsigned int newNbFrames,
0177                                  unsigned int nbDirs)
0178 {
0179   qCDebug(KSIRK_LOG) << (void*)this << svgid;
0180   m_svgid = svgid;
0181   m_width = width*m_zoom;
0182   m_height = height*m_zoom;
0183   frames = newNbFrames;
0184   actFrame = 0;
0185   nbVersions = nbDirs;
0186 
0187   sequenceConstruction();
0188   update();
0189   //    qCDebug(KSIRK_LOG)<<"OUT";
0190 }
0191 
0192 void AnimSprite::nextFrame()
0193 {
0194   if (frames <= 1)
0195   {
0196     return;
0197   }
0198   actFrame++;    // next image
0199 
0200   if (actFrame > (frames-1))
0201   {
0202     actFrame=0; // come back to start
0203     if (m_numberOfShots == 1)
0204     {
0205       setStatic();
0206       m_numberOfShots = std::numeric_limits<unsigned int>::max();
0207       qCDebug(KSIRK_LOG) << "Emiting animationFinished";
0208       emit animationFinished(this);
0209     }
0210     else if (m_numberOfShots != std::numeric_limits<unsigned int>::max())
0211     {
0212       m_numberOfShots--;
0213       qCDebug(KSIRK_LOG) << "numberOfShots is now " << m_numberOfShots ;
0214     }
0215   }
0216   setFrame(actFrame);
0217 }
0218 
0219 void AnimSprite::setFrame(unsigned int numFrame)
0220 {
0221 //   qCDebug(KSIRK_LOG) << " " << numFrame << " look=" << look <<" ; frames="
0222 //           <<frames<<" ; m_frames size="<<m_frames.size();
0223   if (numFrame < (unsigned int)m_frames.size())
0224   {
0225     setPixmap(m_frames[(look-1)*frames+numFrame]);
0226   }
0227 }
0228 
0229 void AnimSprite::moveIt()
0230 {
0231 //   qCDebug(KSIRK_LOG) << "Position of " << (void*)this << " is: "
0232 //     << pos() << " (destination point is: " << destinationPoint << ")";
0233   qreal delta = 5*m_zoom;
0234   switch (KsirkSettings::spritesSpeed())
0235   {
0236     case 0:
0237       delta = 2*m_zoom;
0238       break;
0239     case 1:
0240       delta = 5*m_zoom;
0241       break;
0242     case 2:
0243       delta = 10*m_zoom;
0244       break;
0245     case 3:
0246       setPos(destinationPoint);
0247       destinationPoint = QPointF();
0248       emit atDestination(this);
0249       return;
0250       break;
0251     default:
0252       delta = 5*m_zoom;
0253   }
0254   delta=delta<1.0?1.0:delta;
0255   
0256 //   qCDebug(KSIRK_LOG) << "delta="<<delta;
0257   if (getApproachDestByLeft())
0258   {
0259     setLook(right);
0260     if (x() < destinationPoint.x())
0261     {
0262       if (destinationPoint.x() - x() > delta) setPos(pos() + QPointF(delta,0)) ;
0263       else if (destinationPoint.x() - x() <= 1) setPos(destinationPoint.x(),y());
0264       else /*if (destinationPoint.x() - x() <= delta)*/ setPos(pos() + QPointF(1,0));
0265     }
0266     if (x() > destinationPoint.x())
0267     {
0268       if (getMaxX() - x() > delta) setPos(pos()+QPointF(delta,0));
0269       if (getMaxX() - x() <= delta) setPos(QPointF(destinationPoint.x()<0?destinationPoint.x():0,y()));
0270     }
0271   }
0272   else if (getApproachDestByRight())
0273   {
0274     setLook(left);
0275     if (x() < destinationPoint.x())
0276     {
0277       if (x() > delta) setPos(pos()+QPointF(-delta,0));
0278       if (x() <= delta) setPos(QPointF(getMaxX(),y()));
0279     }
0280     if (x() > destinationPoint.x())
0281     {
0282       if ( x() - destinationPoint.x() > delta) setPos(pos()+QPointF(-delta,0));
0283       else if ( x() - destinationPoint.x() <= 1) setPos(destinationPoint.x(),y());
0284       else /*if ( x() - destinationPoint.x() <= delta)*/ setPos(pos()+QPointF(-1,0));
0285     }
0286   }
0287   else
0288   {
0289     if (x() < destinationPoint.x())
0290     {
0291       setLook(right);
0292       if (destinationPoint.x() - x() > delta) setPos(pos()+QPointF(delta,0));
0293       if (destinationPoint.x() - x() <= 1) setPos(destinationPoint.x(),y());
0294       else /*if (destinationPoint.x() - x() <= delta)*/ setPos(pos()+QPointF(1,0));
0295     }
0296     if (x() > destinationPoint.x())
0297     {
0298       setLook(left);
0299       if (x() - destinationPoint.x() > delta) setPos(pos()+QPointF(-delta,0));
0300       else if (x() - destinationPoint.x() <= 1) setPos(destinationPoint.x(),y());
0301       else /*if (x() - destinationPoint.x() <= delta)*/ setPos(pos()+QPointF(-1,0));
0302     }
0303   }
0304 //   qCDebug(KSIRK_LOG) << "After x, position is: " << pos();
0305   if (getApproachDestByTop())
0306   {
0307     if (y() < destinationPoint.y())
0308     {
0309       if (destinationPoint.y() - y() > delta) setPos(pos()+QPointF(0,delta));
0310       else if (destinationPoint.y() - y() <= delta) setPos(x(),destinationPoint.y());
0311       else /*if (destinationPoint.y() - y() <= delta)*/ setPos(pos()+QPointF(0,1));
0312     }
0313     if (y() > destinationPoint.y())
0314     {
0315       if (getMaxY() - y() > delta) setPos(pos()+QPointF(0,delta));
0316       if (getMaxY() - y() <= delta) setPos(x(),destinationPoint.y()<0?destinationPoint.y():0);
0317     }
0318   }
0319   else if (getApproachDestByBottom())
0320   {
0321     if (y() < destinationPoint.y())
0322     {
0323       if (destinationPoint.y() - y() > delta) setPos(pos()+QPointF(0,-delta));
0324       if (destinationPoint.y() - y() <= delta) setPos(x(), getMaxY() );
0325     }
0326     if (y() > destinationPoint.y())
0327     {
0328       if ( y() - destinationPoint.y() > delta) setPos(pos()+QPointF(0,-delta));
0329       else if ( y() - destinationPoint.y() <= 1) setPos(x(),destinationPoint.y());
0330       else /*if ( y() - destinationPoint.y() <= delta)*/ setPos(pos()+QPointF(0,-1));
0331     }
0332   }
0333   else
0334   {
0335     if (y() < destinationPoint.y())
0336     {
0337       if (destinationPoint.y() - y() > delta) setPos(pos()+QPointF(0,delta));
0338       else if (destinationPoint.y() - y() <= 1) setPos(x(),destinationPoint.y());
0339       else /*if (destinationPoint.y() - y() <= delta)*/ setPos(pos()+QPointF(0,1));
0340     }
0341     if (y() > destinationPoint.y())
0342     {
0343       if (y() - destinationPoint.y() > delta) setPos(pos()+QPointF(0,-delta));
0344       else if (y() - destinationPoint.y() <= 1) setPos(x(), destinationPoint.y());
0345       else /*if (y() - destinationPoint.y() <= delta)*/ setPos(pos()+QPointF(0,-1));
0346     }
0347   }
0348 //   qCDebug(KSIRK_LOG) << "New position of " << (void*)this << " is: " << pos();
0349   nextFrame();
0350   if (pos() == destinationPoint)
0351   {
0352     setStatic();
0353     destinationPoint = QPointF();
0354     emit atDestination(this);
0355   }
0356 }
0357 
0358 bool AnimSprite::isLastFrame() const
0359 {
0360 //    qCDebug(KSIRK_LOG)<<"AnimSprite::isLastFrame actFrame = "<<actFrame<<" frames = "<<frames-1;
0361     return (actFrame == (frames - 1));
0362 }
0363 
0364 void AnimSprite::setDestinationPoint(const QPointF &point)
0365 {
0366     
0367     destinationPoint = point;
0368 }
0369 
0370 const QPointF& AnimSprite::getDestinationPoint() const
0371 {
0372     return  destinationPoint;
0373 }
0374 
0375 int AnimSprite::operator==(const AnimSprite& Arg) const 
0376 {
0377     return (memcmp(this,&Arg,sizeof(AnimSprite)));
0378 }
0379 
0380 void AnimSprite::setDestination(Country* country)
0381 {
0382     destination = country;
0383 }
0384 
0385 Country* AnimSprite::getDestination() 
0386 {
0387     return destination;
0388 }
0389 
0390 void AnimSprite::turnTowardDestination()
0391 {
0392     if (x() <= destinationPoint.x())
0393         setLook(right);
0394     else setLook(left);
0395 }
0396 
0397 bool AnimSprite::isAttacker() const
0398 {
0399     return (isMyState( ATTACKER ));
0400 }
0401 
0402 void AnimSprite::setAttacker()
0403 {
0404     setState ( ATTACKER );
0405 }
0406 
0407 bool AnimSprite::isDefendant() const
0408 {
0409     return (isMyState(DEFENDANT));
0410 }
0411 
0412 void AnimSprite::setDefendant()
0413 {
0414     setState (DEFENDANT);
0415 }
0416 
0417 bool AnimSprite::isNone() const
0418 {
0419     return (isMyState(NONE));
0420 }
0421 
0422 void AnimSprite::setNone()
0423 {
0424     setState (NONE );
0425 }
0426 
0427 /** turn the sprite towards left */
0428 void AnimSprite::setLookLeft()
0429 {
0430   qCDebug(KSIRK_LOG);
0431   setLook(left);
0432 }
0433 
0434 /** tourne le sprite vers la droite */
0435 void AnimSprite::setLookRight()
0436 {
0437   qCDebug(KSIRK_LOG);
0438   setLook(right);
0439 }
0440 /** No descriptions */
0441 bool AnimSprite::looksToLeft() const
0442 {
0443     return (look == left);
0444 }
0445 /** No descriptions */
0446 bool AnimSprite::looksToRight() const
0447 {
0448     return (look == right);
0449 }
0450 
0451 /** Read property of bool approachDestByRight. */
0452 bool AnimSprite::getApproachDestByRight() const
0453 {
0454     return approachDestByRight;
0455 }
0456 
0457 /** Write property of bool approachDestByRight. */
0458 void AnimSprite::setApproachDestByRight( const bool& _newVal)
0459 {
0460   //    qCDebug(KSIRK_LOG);
0461     approachDestByRight = _newVal;
0462     if (_newVal) setApproachDestByLeft(false);
0463 }
0464 
0465 /** Read property of bool approachDestByLeft . */
0466 bool AnimSprite::getApproachDestByLeft () const
0467 {
0468     return approachDestByLeft ;
0469 }
0470 
0471 /** Write property of bool approachDestByLeft . */
0472 void AnimSprite::setApproachDestByLeft ( const bool& _newVal)
0473 {
0474   //    qCDebug(KSIRK_LOG);
0475     approachDestByLeft  = _newVal;
0476     if (_newVal) setApproachDestByRight(false);
0477 }
0478 
0479 /** Read property of bool approachDestByTop. */
0480 bool AnimSprite::getApproachDestByTop() const
0481 {
0482     return approachDestByTop;
0483 }
0484 
0485 /** Write property of bool approachDestByTop. */
0486 void AnimSprite::setApproachDestByTop( const bool& _newVal)
0487 {
0488     approachDestByTop = _newVal;
0489     if (_newVal) setApproachDestByBottom(false);
0490 }
0491 
0492 /** Read property of bool approachDestByBottom . */
0493 bool AnimSprite::getApproachDestByBottom () const
0494 {
0495     return approachDestByBottom ;
0496 }
0497 
0498 /** Write property of bool approachDestByBottom . */
0499 void AnimSprite::setApproachDestByBottom ( const bool& _newVal)
0500 {
0501     approachDestByBottom  = _newVal;
0502     if (_newVal) setApproachDestByTop(false);
0503 }
0504 
0505 /** Return the maximum value for x for this sprite by looking to its including
0506   * background. Necessary for directed approaches.
0507   * Quit with error if there is no background
0508   */
0509 qreal AnimSprite::getMaxX() const
0510 {
0511     if (backGnd)
0512         return backGnd-> pixmap().width();
0513     else
0514     {
0515         KMessageBox::error(nullptr, i18n("Cannot find Max X for sprite: no background!"), i18n("Error!"));
0516         exit(2);
0517     }
0518 }
0519 
0520 /** Return the maximum value for y for this sprite by looking to its including
0521   * background. Necessary for directed approaches.
0522   * Quit with error if there is no background
0523   */
0524 qreal AnimSprite::getMaxY() const
0525 {
0526     if (backGnd)
0527         return backGnd-> pixmap().height();
0528     else
0529     {
0530         KMessageBox::error(nullptr, i18n("Cannot find Max Y for sprite: no background!"), i18n("Error!"));
0531         exit(2);
0532     }
0533 }
0534 
0535 void AnimSprite::setupTravel(Country* src, Country* dest, const QPointF* dpi)
0536 {
0537   qCDebug(KSIRK_LOG) << src->name() << dest->name() << *dpi << (dpi==nullptr?QPointF():*dpi);
0538   if (dpi ==nullptr) AnimSprite::setupTravel(src, dest, src->centralPoint(), dest-> centralPoint());
0539   else AnimSprite::setupTravel(src, dest, src->centralPoint(), *dpi);
0540 }
0541 
0542 /**
0543   * This function chooses the approach mode of a sprite towards its destination:
0544   * if the distance between the origin and the destination is higher than half
0545   * the size of the map and if the origin and destination countries comunicate,
0546   * then the sprite should choose an approach by left or right, through the
0547   * edge of the map.
0548   * This protected method will be called by three public functions specialized
0549   * using as source point, respectivly, the infantryman point, the cavalryman
0550   * point and the cannon point.
0551   */
0552 void AnimSprite::setupTravel(
0553         Country* src, 
0554         Country* dest, 
0555         const QPointF& srcPoint, 
0556         const QPointF& destPoint)
0557 {
0558    qCDebug(KSIRK_LOG) << src->name() << srcPoint << ", " << dest->name() << destPoint ;
0559 
0560   setDestination(dest);
0561   setDestinationPoint(destPoint);
0562   setPos(srcPoint);
0563 
0564   if (!src-> communicateWith(dest))
0565   {
0566       qCCritical(KSIRK_LOG) << "Error in AnimSprite::setupTravel: " << src-> name() << "  and " 
0567               << dest-> name() << " do not communicate!\n";
0568       exit(2);
0569   }
0570   
0571   if ( (qAbs(srcPoint.x() - destPoint.x())) > ((backGnd-> boundingRect().width())/2) && !backGnd->bgIsArena()) 
0572   {
0573       // src is at the right of dest, approch dest by left
0574       if (srcPoint.x() > destPoint.x()) setApproachDestByLeft(true);
0575       // src is at the left of dest, approch dest by right
0576       if (srcPoint.x() < destPoint.x()) setApproachDestByRight(true);
0577   }
0578   else
0579   {
0580       // src is at the right of dest, approch dest by left
0581       if (srcPoint.x() > destPoint.x()) setApproachDestByRight(true);
0582       // src is at the left of dest, approch dest by right
0583       if (srcPoint.x() < destPoint.x()) setApproachDestByLeft(true);
0584   }
0585 
0586   if ( ((qAbs(srcPoint.y() - destPoint.y())) > ((backGnd-> boundingRect().height())/2)) && !backGnd->bgIsArena())
0587   {
0588       // src is under the dest, approch dest by top
0589       if (srcPoint.y() > destPoint.y()) setApproachDestByTop(true);
0590       // src is up to the dest, approch dest by botto
0591       if (srcPoint. y() < destPoint.y()) setApproachDestByBottom(true);
0592   }
0593   else
0594   {
0595       // src is under the dest, approch dest by bottom
0596       if (srcPoint.y() > destPoint.y()) setApproachDestByBottom(true);
0597       // src is up to the dest, approch dest by top
0598       if (srcPoint. y() < destPoint.y()) setApproachDestByTop(true);
0599   }
0600   if (src->pointFlag().x() < dest-> pointFlag().x()) {
0601     setLookRight();
0602   } else {
0603     setLookLeft();
0604   }
0605   setAnimated();
0606   qCDebug(KSIRK_LOG) << "Done";
0607 }
0608 
0609 void AnimSprite::arrival()
0610 {
0611   qCDebug(KSIRK_LOG)<< "at " << destinationPoint ;
0612   if (!backGnd->bgIsArena())
0613   {
0614     qCDebug(KSIRK_LOG)<< "x=" << x() << "pf=" << getDestination()->pointFlag().x();
0615     if (x() < getDestination()-> pointFlag().x())
0616       setLookRight();
0617     else 
0618       setLookLeft();
0619   }
0620   repaint();
0621 }
0622 
0623 /** Return true if the state of the sprite is the argument; false otherwise */
0624 bool AnimSprite::isMyState(State state) const
0625 {
0626     return myState == state;
0627 }
0628 
0629 /**
0630   * returns the current state of the sprite
0631   */
0632 AnimSprite::State AnimSprite::getState() const
0633 {
0634 //    qCDebug(KSIRK_LOG) << "I'm a sprite; my state is : " << myState ;
0635     return myState;
0636 }
0637 
0638 /** sets the new state of the game */
0639 void AnimSprite::setState(AnimSprite::State newState)
0640 {
0641 //    qCDebug(KSIRK_LOG) << "Setting sprite's state to : " << newState << " (was : " << myState << ")";
0642     myState = newState;
0643 }
0644 
0645 void AnimSprite::saveXml(QTextStream& /*xmlStream*/)
0646 {
0647 }
0648 
0649 QPixmap AnimSprite::image(unsigned int numFrame) const
0650 {
0651 //   qCDebug(KSIRK_LOG) << "image(" << numFrame << ") / " << m_frames.size();
0652   if (numFrame >= (unsigned int)m_frames.size())
0653   {
0654     return QPixmap();
0655   }
0656   else
0657   {
0658     return m_frames[(look-1)*frames+numFrame];
0659   }
0660 }
0661 
0662 void AnimSprite::animate()
0663 {
0664   //   qCDebug(KSIRK_LOG) << (void*)this ;
0665   if (!destinationPoint.isNull() && pos() != destinationPoint)
0666   {
0667     moveIt();
0668   }
0669   else if (m_animated && frames > 1)
0670   {
0671     nextFrame();
0672   }
0673   //   qCDebug(KSIRK_LOG) <<"finished for " << (void*)this ;
0674 }
0675 
0676 void AnimSprite::setAnimated(unsigned int numberOfShots)
0677 {
0678   m_numberOfShots = numberOfShots;
0679   m_animated = true;
0680   if (!m_timer.isActive())
0681   {
0682     m_timer.start(200);
0683   }
0684 //   AnimSpritePool::changeable().addSprite(this);
0685 }
0686 
0687 void AnimSprite::setStatic()
0688 {
0689   m_animated = false;
0690   m_timer.stop();
0691 //   AnimSpritePool::changeable().removeSprite(this);
0692 }
0693 
0694 void AnimSprite::applyZoomFactor(qreal zoomFactor)
0695 {
0696   qCDebug(KSIRK_LOG) << "old zoom=" << m_zoom ;
0697   m_zoom *= zoomFactor;
0698   m_width *= m_zoom;
0699   m_height *= m_zoom;
0700   
0701   sequenceConstruction();
0702   update();
0703 }
0704 
0705 void AnimSprite::addDecoration(const QString& svgid, const QRectF& geometry)
0706 {
0707   const qreal dpr = qApp->devicePixelRatio();
0708   QSize size(geometry.size().toSize() * dpr);
0709   QPixmap pm(size);
0710   pm.fill(Qt::transparent);
0711   QPainter p(&pm);
0712   m_renderer->render(&p, svgid);
0713   pm.setDevicePixelRatio(dpr);
0714   QGraphicsPixmapItem* item = new QGraphicsPixmapItem(pm,this);
0715   item->setPos(geometry.topLeft());
0716   item->show();
0717 }
0718 
0719 } // closing namespace Ksirk
0720 
0721 #include "moc_animsprite.cpp"