title: How to create animated explosion in QT
body: <p>I'm creating space shooter game and want to add some special effects:) I mean, when bullet hits the target, enemy will explode.
  I have a few pictures (steps) of explosion, also I'm using QGraphicsPixmapItem class and setPixmap() method to set pixmap of Enemy.
  My bullet and enemy class:</p>
  
  <p>bullet.h</p>
  
  <pre><code>#ifndef BULLET_H
  #define BULLET_H
  
  #include &lt;QGraphicsPixmapItem&gt;
  #include &lt;QGraphicsItem&gt;
  #include &lt;QObject&gt;
  #include &lt;QPropertyAnimation&gt;
  
  class Bullet : public QPropertyAnimation, public QGraphicsPixmapItem{
      Q_OBJECT
  public:
      Bullet(QGraphicsItem * parent=0);
      static int howManyKilled() { return killed; }
      static int howManyMissed() { return missed; }
      static void resetStats() { killed = 0; missed = 0; } // to avoid bad multipler calculate
      void setAccurancy() { accurancy = killed/missed * 100; }
      static double accurancyInPercentage() { return accurancy; }
  public slots:
      void move();
  private:
      static int killed;
      static int missed;
      static double accurancy;
  };
  
  #endif // BULLET_H
  </code></pre>
  
  <p>bullet.cpp</p>
  
  <pre><code>#include "Bullet.h"
  #include &lt;QTimer&gt;
  #include &lt;QGraphicsScene&gt;
  #include &lt;QList&gt;
  #include "Enemy.h"
  #include "Game.h"
  #include &lt;typeinfo&gt;
  #include "levels.h"
  
  extern Game * game; // there is an external global object called game
  int Bullet::killed = 0;
  int Bullet::missed = 0;
  double Bullet::accurancy = 0;
  
  Bullet::Bullet(QGraphicsItem *parent): QGraphicsPixmapItem(parent){
      // draw graphics
      setPixmap(QPixmap(":/images/res/images/bullets/bullet.png"));
      missed++; // increse missed when bullet is created
  
      // make/connect a timer to move() the bullet every so often
      QTimer * timer = new QTimer(this);
      connect(timer,SIGNAL(timeout()),this,SLOT(move()));
  
      // start the timer
      timer-&gt;start(3);
  }
  /*
  void Bullet::explosion()
  {
      setPixmap(QPixmap(":/images/res/images/effects/explosion/1_12.png"));
  }
  */
  void Bullet::move(){
      // get a list of all the items currently colliding with this bullet
      QList&lt;QGraphicsItem *&gt; colliding_items = collidingItems();
  
      // if one of the colliding items is an Enemy, destroy both the bullet and the enemy
      for (int i = 0, n = colliding_items.size(); i &lt; n; ++i){
          if (typeid(*(colliding_items[i])) == typeid(Enemy)){
              // increase the score
              game-&gt;score-&gt;increase();
  
              //play explosion animation
              //Bullet::explosion();
              //QTimer::singleShot()
              //explosion = new QPropertyAnimation(this);
              //explosion-&gt;setDuration(300);
              //explosion-&gt;
  
  
              // remove them from the scene (still on the heap)
              scene()-&gt;removeItem(colliding_items[i]);
              scene()-&gt;removeItem(this);
  
              // delete them from the heap to save memory
              delete colliding_items[i];
              delete this;
  
              killed++;
              missed--; // decrese missed if bullet colide with enemy
              if((killed+1) % 9 == 0)
              {
                  game-&gt;level-&gt;Levels::incrementLevels();
                  game-&gt;score-&gt;Score::addToSum(); /// TODO
              }
  
              //qDebug() &lt;&lt; "Already killed: " &lt;&lt; killed;
              //qDebug() &lt;&lt; "Already missed: " &lt;&lt; missed;
              // return (all code below refers to a non existint bullet)
              return;
          }
      }
  
      // if there was no collision with an Enemy, move the bullet forward
      setPos(x(),y()-1);
      // if the bullet is off the screen, destroy it
      if (pos().y() &lt; 0){
          scene()-&gt;removeItem(this);
          delete this;
      }
  }
  </code></pre>
  
  <p>enemy.h</p>
  
  <pre><code>#ifndef ENEMY_H
  #define ENEMY_H
  
  #include &lt;QGraphicsPixmapItem&gt;
  #include &lt;QObject&gt;
  #include &lt;QGraphicsItem&gt;
  
  class Enemy: public QObject,public QGraphicsPixmapItem{
      Q_OBJECT
  public:
      Enemy(QGraphicsItem * parent=0);
  public slots:
      void move();
  };
  
  #endif // ENEMY_H
  </code></pre>
  
  <p>enemy.cpp</p>
  
  <pre><code>#include "Enemy.h"
  #include &lt;QTimer&gt;
  #include &lt;QGraphicsScene&gt;
  #include &lt;QList&gt;
  #include &lt;stdlib.h&gt; // rand()
  #include &lt;ctime&gt;
  #include "Game.h"
  #include "hp.h"
  #include &lt;typeinfo&gt;
  
  extern Game * game;
  extern unsigned int width;
  extern unsigned int height;
  
  Enemy::Enemy(QGraphicsItem *parent): QObject(), QGraphicsPixmapItem(parent){
      //set random x position
      //srand( time( NULL ) );
      int random_number = rand()% (width-200) + 100;
      //qDebug() &lt;&lt; random_number;
      setPos(random_number,0);
  
      // drew the rect
      setPixmap(QPixmap(":/images/res/images/enemies/3.png"));
      setTransformOriginPoint(50,50);
      //setRotation(180);
  
      // make/connect a timer to move() the enemy every so often
      QTimer * timer = new QTimer(this);
      connect(timer,SIGNAL(timeout()),this,SLOT(move()));
  
      // start the timer
      timer-&gt;start(10);
  }
  
  void Enemy::move(){
      ///////////////////////// COLISIONS /////////////////////////////////////
      // get a list of all the items currently colliding with this bullet
      QList&lt;QGraphicsItem *&gt; colliding_items = collidingItems();
  
      // if one of the colliding items is an Enemy, destroy both the bullet and the enemy
      for (int i = 0, n = colliding_items.size(); i &lt; n; ++i){
          if (typeid(*(colliding_items[i])) == typeid(Player)){
              // increase the score
              game-&gt;hp-&gt;decrementLives();
  
              // remove them from the scene (still on the heap)
              scene()-&gt;removeItem(this);
  
              // delete them from the heap to save memory
              delete this;
  
              // return (all code below refers to a non existint bullet)
              return;
          }
      }
      ///////////////////////////////////////////////////////////////////////////////////////
      // if there was no collision with an Enemy, move the bullet forward
      // move enemy down
  
      if (Levels::howManyLevels() &lt; 10)
      {
          setPos(x(),y() + Levels::howManyLevels());
      }
      else
      {
          setPos(x(),y() + 10);
      }
  
      // destroy enemy when it goes out of the screen
      if (pos().y() &gt; height){
          //decrease the health
          game-&gt;hp-&gt;decrementLives();
  
          scene()-&gt;removeItem(this);
          delete this;
      }
  }
  </code></pre>