PyGame Keyboard Input

Run rectangle run!

Introduction

In this section we will look at how you can get keyboard input in PyGame and use that to interact with elements in your game. We will then come back to images and text which we will use to make your games more engaging.

Getting Set Up

Before we begin, let's create a new file (call it movement.py) and copy in the template code from earlier on.

We'll also add in a rectangle to the screen which will represent our character for now (we will build it to be more impressive with an image in a later tutorial).

  • # Colours
  •  
  • CHARACTER = (255, 30, 70)
  •   looping = True
  •  
  •   characterX = 10
  •   characterY = 30
  •   characterWidth = 50
  •   characterHeight = 70
  •     # Processing
  •  
  •     character = pygame.Rect(characterX, characterY, characterWidth, characterHeight)
  •     WINDOW.fill(BACKGROUND)
  •     pygame.draw.rect(WINDOW, CHARACTER, character)

Our simple characterOnce you've saved your file with the template code in it and the addititions detailed above, run the file to make sure you've set it up ok. You should have a white window with a red rectangle at the top left which is going to represent our character.

He's not very exciting right now but we'll work on that later.

You'll notice we've changed the values for the X and Y coordinate of the character to be variables rather than hard coded values. This is so that we can easily manipulate these values. We set the initial values for these variables outside the loop so that they get set up once before the game loop begins.

Events

Keyboard input is handled within PyGame as events. There are a few ways in which we can handle these events. Each has their own characteristics and is suited to different situations.

get_pressed

The method you will probably use the most is by making use of the following command :

keys = pygame.key.get_pressed()

Running this command will set the variable keys to a dictionary with all the keys on the keyboard. The value for each item will be either True if the key is currently pressed, or False if the key is currently not pressed.

Add the following code to your file just below the for loop for events :

  •         pygame.quit()
  •         sys.exit()
  •  
  •     pressed = pygame.key.get_pressed()
  •     if (pressed[K_RIGHT] or pressed[K_d]) :
  •       characterX = characterX + 3

If you save and run the script you will notice that you can press either the Right arrow key or the d key and your character will move to the right. You can hold either of the keys down and the character will move continuously.

Increase and decrease the value that gets added to characterX and see what effect this has on the movement of your character.

Now let's make it so that our character can also move to the left :

  •         pygame.quit()
  •         sys.exit()
  •  
  •     pressed = pygame.key.get_pressed()
  •     if (pressed[K_RIGHT] or pressed[K_d]) :
  •       characterX = characterX + 3
  •     if (pressed[K_LEFT] or pressed[K_a]) :
  •       characterX = characterX - 3

We have implemented this as a series of if statements instead of if, elif statements as the former will treat them as separate tests allowing us to act upon several key presses simultaneously whereas the latter would only act upon the first True item. By doing this with if statements we could hold down Right and Down together to do diagonally for instance.

Now we will add in up and down as well. Have a go at doing this by yourself but if you get stuck you can reveal the code below.

  •         pygame.quit()
  •         sys.exit()
  •  
  •     pressed = pygame.key.get_pressed()
  •     if (pressed[K_RIGHT] or pressed[K_d]) :
  •       characterX = characterX + 3
  •     if (pressed[K_LEFT] or pressed[K_a]) :
  •       characterX = characterX - 3
  •     if (pressed[K_DOWN] or pressed[K_s]) :
  •       characterY = characterY + 3
  •     if (pressed[K_UP] or pressed[K_w]) :
  •       characterY = characterY - 3

Running your code now your character should be able to move in all four directions as well as diagonally.

KEYDOWN and KEYUP

The other method by which we can respond to key presses is to use the events which are fired when a key is pressed. Unlike the previous method they will only fire once, even if you hold the key down.

Let's make it so that if we press the r key it will reset the position of the character.

  •         pygame.quit()
  •         sys.exit()
  •       if event.type == pygame.KEYDOWN and event.key == K_r :
  •         characterX = 10
  •         characterY = 30
  •  
  •     pressed = pygame.key.get_pressed()

If you save and run your code now you should find that when you press the r key on the keyboard your character moves back to it's starting position. If you press and hold the r key and press other movement keys you should move around without constantly being reset back to the starting position.

Now let's get the character to move to another position when the r key is released.

  •       if event.type == pygame.KEYDOWN and event.key == K_r :
  •         characterX = 10
  •         characterY = 30
  •       if event.type == pygame.KEYUP and event.key == K_r :
  •         characterX = 340
  •         characterY = 200
  •  
  •     pressed = pygame.key.get_pressed()

Now when you press and hold the r key the character will move to the starting position, you can move your character around and when you release the r key the character will move to the bottom right of the window.

Boundaries

At the moment our character has free reign of movement. If we hold the keys down our character will happily travel beyond the window borders. Let's fix that and keep him in the window.

There are a few ways in which we can achieve this (in fact nearly unlimited if you're creative enough) but we'll look at two of the most common ways. It might be worth making a copy of your file as a backup at this point.

Edge is a wall

The first method involves treating the edge of the window like a wall. When the character hits the wall they can't travel any further in that direction. We implement this as a series of if statementes in the processing section of our game loop that check if the character is out of bounds and moves them back if so.

  •     # Processing
  •  
  •     if (characterX + characterWidth > WINDOW_WIDTH) :
  •       characterX = characterX - 3
  •  
  •     character = pygame.Rect(characterX, characterY, characterWidth, characterHeight)

If you run your code now your character shouldn't be able to move off the right side of the window.

edge mathematicsWe have to do a little bit of mathematics here as the coordinates for our rectangle are actually for the top left of the rectangle and we need to check if the right edge of the rectangle is touching the right edge of the window or not.

Now have a go and see if you can stop your character from moving off the left side of the window.

  •     # Processing
  •  
  •     if (characterX + characterWidth > WINDOW_WIDTH) :
  •       characterX = characterX - 3
  •     if (characterX < 0) :
  •       characterX = characterX + 3
  •  
  •     character = pygame.Rect(characterX, characterY, characterWidth, characterHeight)

Pop out the other side

The other popular method for handling the edge of the window is to transport the character to the opposite edge. This is also not to tricky to do. We'll implement this method for up and down.

Place the code below between the code you just entered for the left and right edges and your code to create the Rect object.

  •  
  •     if (characterY + characterHeight > WINDOW_HEIGHT) :
  •       characterY = 0
  •  
  •     character = pygame.Rect(characterX, characterY, characterWidth, characterHeight)

Now have a go and see if you can get your character to pop out the bottom of the window when they hit the top of the window.

  •  
  •     if (characterY + characterHeight > WINDOW_HEIGHT) :
  •       characterY = 0
  •     if (characterY < 0) :
  •       characterY = WINDOW_HEIGHT - characterHeight
  •  
  •     character = pygame.Rect(characterX, characterY, characterWidth, characterHeight)

Activities

Even though our program is still quite basic we can still tinker and create the beginnings of some interesting games.

Have a go at the following :

1. Can you reverse the movement so that when you press up the character goes down etc?

2. Can you add a second character and make it so that the arrow keys move one character and the WASD keys move the other character?

3. Let's see if we can make a simple chase game. Make the movement for one character reversed

4. Now set it so that one character hits a wall at the edge of the window and the other character pops out the other side instead.