Time for action - Keeping multiple animations in sync

Now we'll start implementing the coin class. We can use a simple QGraphicsEllipseItem object, but we'll need to animate its properties, so let's create a new Coin class and derive it from QObject and QGraphicsEllipseItem. Define two properties: opacity of the qreal type and rect of the QRect type. This is done only by the following code:

class Coin : public QObject, public QGraphicsEllipseItem
{
Q_OBJECT
Q_PROPERTY(qreal opacity READ opacity WRITE setOpacity)
Q_PROPERTY(QRectF rect READ rect WRITE setRect)
//...
};

No function or slot was added, because we simply used built-in functions of QGraphicsItem and associated them with the properties.

If you want an item that inherits from QObject and QGraphicsItem, you can directly inherit QGraphicsObject. Moreover, it already registers all general QGraphicsItem properties in the metasystem, including pos, scale, rotation, and opacity. All properties come with corresponding notification signals, such as  opacityChanged(). However, when you inherit QGraphicsObject, you cannot, at the same time, inherit QGraphicsEllipseItem or any other item class. So in this case, we will need to either implement painting of the ellipse manually or add a child QGraphicsEllipseItem that can perform the painting for us.

Next, we'll create the explode() function that will start some animations when the player collects the coin. Create a Boolean private field in the class and use it to ensure that each coin can only explode once:

void Coin::explode()
{
if (m_explosion) {
return;
}
m_explosion = true;
//...
}

We want to animate our two properties by two QPropertyAnimation objects. One fades the coin out, while the other scales the coin in. To ensure that both animations get started at the same time, we use QParallelAnimationGroup, as follows:

QPropertyAnimation *fadeAnimation = 
new QPropertyAnimation(this, "opacity");
//... QPropertyAnimation *scaleAnimation = new QPropertyAnimation(this, "rect");
//... QParallelAnimationGroup *group = new QParallelAnimationGroup(this); group->addAnimation(scaleAnimation); group->addAnimation(fadeAnimation); connect(group, &QParallelAnimationGroup::finished, this, &Coin::deleteLater); group->start();