If you’re enjoying this tutorial, please consider supporting it by purchasing a book through one of the links on my site, such as this one ->
This is part of an ongoing series where we write a complete 2D game engine in C++ and SFML. A new tutorial is released every Monday. You can find the complete list of tutorials here and download the source code from the projects GitHub page.
Last week we started our animation system by animating our Viking character, however, there were a number of major limitations. Firstly we only have the one animation: idle; in our final game, our character is definitely going to need to be able to do more than just stand around! And secondly, it does not matter which direction we were moving we always faced right (the direction the sprites are facing in the sprite sheet). So in this tutorial, we will fix these issues. To do that we need to:
- Create the concept of a facing direction.
- Track which direction the character is currently facing and flip the sprites if necessary.
- Add a new walking animation.
- Have some way of switching between idle and walking depending on the characters movement speed.
We’ll start by implementing the facing direction. To do this we’ll create a new enum called FacingDirection, and a couple of methods to get and set this direction, in our Animation class. We’ll also pass an animations direction in its constructor. This does mean that all sprites for a certain animation need to be facing in the same direction, which is generally the case but its something we can change in future if we need to.
- To flip a sprite we multiply its width by 1 which inverts the number (if it was positive it becomes negative and if it was negative it becomes positive). For example:
We want to flip a frame with a position of 0 and a width of 32.
We first add the width of the sprite to the x position so that the sprites position is now set to the top right rather that the top left.
However, this means that the sprite’s width is wrong. It will either be drawing the next sprite or if there isn’t one be trying to draw something that isn’t there. To rectify this we need to invert its width so that it points in the opposite direction. 32 * -1 = -32.
This has the same effect as scaling the image by -1 on the x-axis and flips the sprite! Job done. And when we want to flip the sprite back, the process works in reverse:
- 32 + -32 = 0
- -32 * -1 = 32
We’ll now need a way to set the direction for the current animation in our component so that anyone with a reference to our component can flip our sprites.
As we need to pass a direction to the animation constructor we need to change the OnCreate method in SceneGame where we create our idle animation. We pass the direction of the character as they appear in the sprite sheet; for example, as our Viking is facing right in the sprite sheet, we pass in FacingDirection::Right.
When we look into the characters physics, we’ll implement a different method of determining the direction of the character but for now, we can simply set the direction based on the keys being pressed by the player i.e. we assume the character is moving right if they are pressing right on the keyboard. We’ll see in a later tutorial why this is not always the best way of doing things. Also ideally we do not want our keyboard component to know anything about our animation system so in future we’ll look at implementing an event system to allow for inter-system communication.
We need to change the keyboard Update method to set the direction based on the key that is currently being pressed.
Now when you run the game and use the arrow keys to move our little Viking around the screen, he will face the direction you are moving.
We still only have the one animation though, let’s rectify that by creating a walk animation.
This is pretty much the same process as the idle animation, except there’s one additional frame, and of course, the frames point to different sprites in the sprite sheet.
If you run the game now you will be disappointed as the character will still stay in its idle state. This is because the first animation we add becomes the initial animation (i.e. idle) and we have not provided any method to switch between the two. We’ll do just that in the keyboard movement component after we update the characters position. Again this is not the ideal way to accomplish this and will be something we change when we look into player physics.
With that done our character will now change its animation depending on his movement speed.
As a side note, I also doubled the players move speed (100 to 200) in C_KeyboardMovement to make him a bit nipper traversing the screen.
As always, if you have any suggestions for what you would like covered or are having any trouble implementing a feature, then let me know in the comments and I’ll get back to you as soon as I can. Thank you for reading 🙂