Pygame RPG Tutorial – Player Movement

Welcome to tutorial number 4 in our Pygame RPG series.

Introduction

This Pygame RPG tutorial and the next are both focused on implementing movement and physics, allowing for a complete system where our Player can move, jump and interact with the ground he is standing on.

The entirety of this tutorial is based off a single function which we need to create in the Player class, called the move function. We already defined the function name earlier, so we just have to add in the code now.


Player Running

The first thing we are going to do is add a little if statement to determine whether the Player is running or not. Since we are going to add friction and acceleration into this game, even if you move your hand off the “move forward” button, the player will still be moving for about half a second (momentum).

The code below will ensure that the Player is not regarded as “running” when he is in such a state where his velocity is really low (compared to normal running speed).

We use abs() to return the magnitude since the velocity can be in the negative direction (the left direction) which would cause inaccuracies.

    def move(self):

          # Will set running to False if the player has slowed down to a certain extent
          if abs(self.vel.x) > 0.3:
                self.running = True
          else:
                self.running = False

Although we don’t have anything like this implemented yet, this would also be a good way to add a new state for walking. For example, if the velocity is below 0.5, then self.running will become False and self.walking will become True.


Key Presses

This is the part of the move function that actually detects the key presses and accelerates the player in a certain direction. Using pygame.key.get_pressed() we can return the keys that have been pressed.

          # Returns the current key presses
          pressed_keys = pygame.key.get_pressed()

          # Accelerates the player in the direction of the key press
          if pressed_keys[K_LEFT]:
                self.acc.x = -ACC
          if pressed_keys[K_RIGHT]:
                self.acc.x = ACC 

The selection statements later on determine whether to increase acceleration towards the right or the left, based on the which key was pressed. (These key presses are for the right and left arrow keys, though you could change them)

Next up is some basic Physics. If you know the equations of motion, then you will understand the following lines. Otherwise just copy it and you’re good.

          # Formulas to calculate velocity while accounting for friction
          self.acc.x += self.vel.x * FRIC
          self.vel += self.acc
          self.pos += self.vel + 0.5 * self.acc  # Updates Position with new values

The basic gist of it though is that acceleration is calculated based off velocity and friction, and the position is updated based off how much distance was covered (which is calculated based off the acceleration and velocity).

You could create an alternative version, where left and right keypresses directly increase or decrease the x position variable (self.pos.x). But of course, you’ll lose out on concepts like acceleration and friction then.

Having an acceleration and friction system is actually pretty beneficial. With a slight tweak you could change the friction values for different ground surfaces (Ice, sand) or you could temporarily speed up the player by just changing the acceleration value.


Warping the Player

          # This causes character warping from one point of the screen to the other
          if self.pos.x > WIDTH:
                self.pos.x = 0
          if self.pos.x < 0:
                self.pos.x = WIDTH
        
          self.rect.midbottom = self.pos  # Update rect with new pos   

If you want to disable this feature, swap the 0 and WIDTH values of self.pos.x statements within the if statements. This will create the opposite effect, not allowing the Player to move past the edge.

The complete Player move() function, constructed after combining all of the previous blocks of code.

    def move(self):
          # Keep a constant acceleration of 0.5 in the downwards direction (gravity)
          #self.acc = vec(0,0.5)

          # Will set running to False if the player has slowed down to a certain extent
          if abs(self.vel.x) > 0.3:
                self.running = True
          else:
                self.running = False

          # Returns the current key presses
          pressed_keys = pygame.key.get_pressed()

          # Accelerates the player in the direction of the key press
          if pressed_keys[K_LEFT]:
                self.acc.x = -ACC
          if pressed_keys[K_RIGHT]:
                self.acc.x = ACC 

          # Formulas to calculate velocity while accounting for friction
          self.acc.x += self.vel.x * FRIC
          self.vel += self.acc
          self.pos += self.vel + 0.5 * self.acc  # Updates Position with new values

          # This causes character warping from one point of the screen to the other
          if self.pos.x > WIDTH:
                self.pos.x = 0
          if self.pos.x < 0:
                self.pos.x = WIDTH
        
          self.rect.midbottom = self.pos  # Update rect with new pos 

Don’t forget that move is just a function. We need to actually call it before anything happens. And as we explained earlier, everything that needs to be repeated every frame, goes into the game loop. Thus we add player.move() into the game loop as shown below.

while True:      
      ...
      ...
      player.move()
      ...
      displaysurface.blit(player.image, player.rect)

The order can be switched up a bit here and there, but in this case just keep the move function before the player is actually rendered.

And now, the results of all our hard work.

There is a slight bug being caused due to friction, but once we implement gravity, it will fix itself so don’t worry about it.


Next Section

As expected, the next step is to implement Gravity and Jumping mechanics. Since both of them go hand in hand so we will discuss them together. You can expect the next tutorial to be very conceptual and interesting!


This marks the end of the Pygame RPG “Player Movement” Tutorial. Any suggestions or contributions for CodersLegacy are more than welcome. Questions regarding the article content can be asked in the comments section below.

Subscribe
Notify of
guest
7 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments