- Game Programming using Qt 5 Beginner's Guide
- Pavel Strakhov Witold Wysota Lorenz Haas
- 413字
- 2021-08-27 18:31:14
What just happened?
First, we call the scene's QGraphicsScene::collidingItems() function, which takes the item for which colliding items should be detected as a first argument. With the second, optional argument, you can define how the collision should be detected. The type of that argument is Qt::ItemSelectionMode, which was explained earlier. By default, an item will be considered colliding with m_player if the shapes of the two items intersect.
Next, we loop through the list of found items and check whether the current item is a Coin object. This is done by trying to cast the pointer to Coin. If it is successful, we explode the coin by calling explode(). Calling the explode() function multiple times is no problem, since it will not allow more than one explosion. This is important since checkColliding() will be called after each movement of the player. So the first time the player hits a coin, the coin will explode, but this takes time. During this explosion, the player will most likely be moved again and thus collides with the coin once more. In such a case, explode() may be called multiple times.
The collidingItems() function will always return the background items as well, since the player item is above all of them most of the time. To avoid the continuous check if they actually are coins, we use a trick. Instead of using QGraphicsPixmapItem directly, we subclass it and reimplement its virtual shape() function, as follows:
QPainterPath BackgroundItem::shape() const { return QPainterPath(); }
We already used the QPainterPath class in the previous chapter. This function just returns an empty QPainterPath. Since the collision detection is done with the item's shape, the background items can't collide with any other item since their shape is permanently empty. Don't try this trick with boundingRect() though, because it must always be valid.
Had we done the jumping logic inside Player, we could have implemented the item collision detection from within the item itself. QGraphicsItem also offers a collidingItems() function that checks against colliding items with itself. So scene->collidingItems(item) is equivalent to item->collidingItems().