This is tutorial number 6 in our Pygame RPG series.
To complete the Player sprites movement mechanic, we have one feature left called animations. If you have any experience with videos and animations, you’ll know that a Video is created by running many still images together to create a moving effect.
Here we are doing the same thing. We have almost 10 different still frames of our Player in various poses while moving. We will rapidly cycle through these to give the illusion of a fluidly moving character.
We’re going to add two new movement related variables to the player class, right along with the
The new addition
self.running is a variable we will be using the track whether the Player is currently standing still or moving/running. Normally there may three modes, standing, walking and running. Since this is a simple 2-D game though, we’ll stick with just two standing and running. (You can always add more using these concepts taught here though)
# Movement self.jumping = False self.running = False self.move_frame = 0
self.move_frame is another very important variable we will be using to track the current frame of the character being displayed.
Loading the Animations
Before we get into anything, we should load up our animations. As we explained earlier, we have several different images of the player in different poses while running. All of these images have been imported into pygame using the
The above image is a strip showing all the various animations poses of our player. You can download the animations that we’re using in our code using the button at the bottom of the page and then inspect them indivudally.
# Run animation for the RIGHT run_ani_R = [pygame.image.load("Player_Sprite_R.png"), pygame.image.load("Player_Sprite2_R.png"), pygame.image.load("Player_Sprite3_R.png"),pygame.image.load("Player_Sprite4_R.png"), pygame.image.load("Player_Sprite5_R.png"),pygame.image.load("Player_Sprite6_R.png"), pygame.image.load("Player_Sprite_R.png")] # Run animation for the LEFT run_ani_L = [pygame.image.load("Player_Sprite_L.png"), pygame.image.load("Player_Sprite2_L.png"), pygame.image.load("Player_Sprite3_L.png"),pygame.image.load("Player_Sprite4_L.png"), pygame.image.load("Player_Sprite5_L.png"),pygame.image.load("Player_Sprite6_L.png"), pygame.image.load("Player_Sprite_L.png")]
We’ve then placed all these images into a list, which we will iterate through in order to produce the moving player effect.
You need to place these animations at the very top of the program, and not within any of the classes. This makes it accessible from any Class.
The Animation Update function
The majority of this tutorial will be based on the Animation update function for the Player class. This function is in charge of changing the movement frame of the Player if he is moving.
Remember, only one frame must be updated per game cycle. This means that the update function will not cycle through all of the movement frames at once, rather it will just keep incrementing them by one, every time it is called.
def update(self): # Return to base frame if at end of movement sequence if self.move_frame > 6: self.move_frame = 0 return
The above code represents the start of the
update() method. It is responsible to reset the movement frame back to 0, if the self.move_frame value has gone above 6. The reason for the “6” is because we have 7 frames (we start from 0). Remember, the more frames you have, the smoother your animation will look.
The below code is the most important, as it’s responsible for actually changing the frames. To ensure that the frames aren’t updated while the Player is standing still, one of the two requirements is that the Player must be in a state of running. The other requirement is that the player must not be in a state of jumping.
If you can’t remember how self.running is set to True, check the movement tutorial.
# Move the character to the next frame if conditions are met if self.jumping == False and self.running == True: if self.vel.x > 0: self.image = run_ani_R[self.move_frame] self.direction = "RIGHT" else: self.image = run_ani_L[self.move_frame] self.direction = "LEFT" self.move_frame += 1
If these conditions have been met, it’s time to determine which frame will be shown. First we determine the direction the player is going in. If the player’s velocity is greater than 0, then that means that he is moving in the right direction. Otherwise he is going in the left.
Once a decision has been made, the image of the player is updated using the list of images we created earlier. The
self.move_frame variable determines which image is to be used. Finally, the direction of the Player is updated. This will come in handy later on.
The purpose of this final section of the update method, is to return the Player to his original standing position if he is (almost) standing still, but the incorrect movement is showing.
# Returns to base frame if standing still and incorrect frame is showing if abs(self.vel.x) < 0.2 and self.move_frame != 0: self.move_frame = 0 if self.direction == "RIGHT": self.image = run_ani_R[self.move_frame] elif self.direction == "LEFT": self.image = run_ani_L[self.move_frame]
Removing this piece could result in the correct stuck in a mid-way run pose while actually standing still.
Finally, to pull it all together add the
player.update() to the Game loop as shown below.
while True: ... ... player.update() player.move()
Below is a short video showing how far we’ve gotten with our game so far.
The movement isn’t perfect. It’s a bit clunky due to a low amount of frames and some “not-very-professional” editing, but it’s pretty passable. You can do some editing on the images and increase the number of frames to produce a better effect.
Now we have just one major Player related mechanic left to implement. The Attacking code and attack animations which will enable the Player to actually fight against the Enemies we will be creating later on.
or go to our Code review where code from tutorial 1 – 6 is compiled and available for download
This marks the end of the Pygame RPG Tutorial – Movement Animations. Any suggestions or contributions are more than welcome. Questions regarding the article content can be asked in the comments section below.