Time for action - Creating an item for Benjamin
Let's create a new Qt Widgets project and start making our game. Since the project will become more complex than our previous projects, we will not be giving you precise instructions for editing the code. If at any time you are unsure about the changes you make, you can look at the reference implementation provided with the book. It also contains the image files you can use to implement the game.
Let's now look at how we can mobilize Benjamin. First, we need a custom item class for him. We call the Player class and choose QGraphicsPixmapItem as the base class, because Benjamin is a PNG image. In the item's Player class, we further create a private field of integer type and call it m_direction. Its value signifies in which direction Benjamin walks—left or right—or if he stands still. Next, we implement the constructor:
Player::Player(QGraphicsItem *parent) : QGraphicsPixmapItem(parent) , m_direction(0) { QPixmap pixmap(":/elephant"); setPixmap(pixmap); setOffset(-pixmap.width() / 2, -pixmap.height() / 2); }
In the constructor, we set m_direction to 0, which means that Benjamin isn't moving at all. If m_direction is 1, Benjamin moves right, and if the value is -1, he moves left. In the body of the constructor, we set the image for the item by calling setPixmap(). The image of Benjamin is stored in the Qt Resource system; thus, we access it through QPixmap(":/elephant"), with elephant as the given alias for the actual image of Benjamin. Finally, we use the setOffset() function to change how the pixmap is positioned in the item's coordinate system. By default, the origin point corresponds to the top-left corner of the pixmap, but we prefer to have it at the center of the pixmap so that applying transformations is easier.
Next, we create a getter and setter function for the m_direction field:
int Player::direction() const { return m_direction; } void Player::setDirection(int direction) { m_direction = direction; if (m_direction != 0) { QTransform transform; if (m_direction < 0) { transform.scale(-1, 1); } setTransform(transform); } }
The direction() function is a standard getter function for m_direction returning its value. The setDirection() setter function additionally checks in which direction Benjamin is moving. If he is moving left, we need to flip his image so that Benjamin looks to the left, the direction in which he is moving. If he is moving toward the right, we restore the normal state by assigning an empty QTransform object, which is an identity matrix.
So, we now have our item of the Player class for the game's character, which shows the image of Benjamin. The item also stores the current moving direction, and based on that information, the image is flipped vertically if needed.