How To Get Keyboard Input In Pygame

Keyboard Input Options

There are two different ways of getting keyboard input in pygame:

  • Using the event handler
  • Using the key_pressed() function

Both methods have their pros and cons. Let’s look at each in turn to see how they work

Using the event handler

Pressing a key will trigger an event in pygame, which will be added to the event queue. If you need a refresher on the event handler, check out the tutorial in the sidebar.

KEYDOWN events

Here we have the starter code for a game with an event handler setup to look for QUIT events. There is also a check on line 16 for a KEYDOWN event, which triggers a print statement. Run this code and try pressing different keys on the keyboard to see the result.

				
					import pygame

pygame.init()

SCREEN_WIDTH = 800
SCREEN_HEIGHT = 600

screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))

run = True
while run:

  for event in pygame.event.get():
    if event.type == pygame.QUIT:
      run = False

    if event.type == pygame.KEYDOWN:
      print(event)

pygame.quit()
				
			

You should see an output in the console that displays information on the event. One of these values is the key, which is a unique ID that represents each key and this is what we will use to check for specific key presses.

Let’s use this to check for the “a” key being pressed by adding the specific check on line 17:

				
					import pygame

pygame.init()

SCREEN_WIDTH = 600
SCREEN_HEIGHT = 400

screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))

run = True
while run:

  for event in pygame.event.get():
    if event.type == pygame.QUIT:
      run = False

    if event.type == pygame.KEYDOWN:
      if event.key == pygame.K_a:
        print("A")

pygame.quit()
				
			

When you press the “a” key on your keyboard, your console should print out “A”.

Notice that the detection only happens once. So even if you hold down the key, it will only print out once. This is because the keydown event has already happened and to repeat it, you would need to release the key and press it again.

Continuous Input

This is fine for single shot events, but if we want an action to continue being performed while the key is pressed, such as player movement for example, we would need to add trigger variables. These variables are set to True when the key is pressed and set back to False when the key is released.

The updated code below adds a trigger variable running on line 10. Notice the event handler no longer prints anything, instead it sets the trigger variable to True. At this point I also introduce the KEYUP event on line 21, which works in the same way but is triggered when a key is released. Lastly, a print statement is called on line 25, which runs when the trigger variable is True.

				
					import pygame

pygame.init()

SCREEN_WIDTH = 600
SCREEN_HEIGHT = 400

screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))

running = False

run = True
while run:

  for event in pygame.event.get():
    if event.type == pygame.QUIT:
      run = False

    if event.type == pygame.KEYDOWN:
      if event.key == pygame.K_a:
        running = True

    if event.type == pygame.KEYUP:
      if event.key == pygame.K_a:
        running = False

  if running == True:
    print("Running")

pygame.quit()
				
			

If all went well, you should have seen a constant stream out “Running” being printed in the console for as long as you held down the “a” key.

Multiple Keys

What if we want to check for multiple keys at the same time, say for example we’re making a platformer and the “a” key is used to run but if you hold down “shift” at the same time, the player will go into a sprint and run faster.

Try this out yourself by changing if event.key == pygame.K_a: to if event.key == pygame.K_a and event.key == pygame.K_LSHIFT: to check for both keys together.

Why didn’t that work?

Well, each keypress is a separate event. When we iterate through them with this for loop, we are looking at them in isolation so it isn’t possible to one event to contain both keys. This is one of the drawbacks of using the event handler to take key presses, however it can be solved.

We can do this by using the trigger variables from earlier. We already created a variable for running, now we add a second variable for sprinting and set the both to False

				
					running = False
sprinting = False
				
			

Now we can update the event handler to check for the “shift” key being pressed and update the trigger variable accordingly.

				
					if event.type == pygame.KEYDOWN:
  if event.key == pygame.K_a:
    running = True
  elif event.key == pygame.K_LSHIFT:
    sprinting = True

if event.type == pygame.KEYUP:
  if event.key == pygame.K_a:
    running = False
  elif event.key == pygame.K_LSHIFT:
    sprinting = False
				
			

And lastly update the print statement to check if the running and sprinting variables are both True or if only one is.

				
					if sprinting == True and running == True:
  print("Sprinting")
elif running == True:
  print("Running")
				
			

The complete code then becomes:

				
					import pygame

pygame.init()

SCREEN_WIDTH = 600
SCREEN_HEIGHT = 400

screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))

running = False
sprinting = False

run = True
while run:

  for event in pygame.event.get():
    if event.type == pygame.QUIT:
      run = False

    if event.type == pygame.KEYDOWN:
      if event.key == pygame.K_a:
        running = True
      elif event.key == pygame.K_LSHIFT:
        sprinting = True

    if event.type == pygame.KEYUP:
      if event.key == pygame.K_a:
        running = False
      elif event.key == pygame.K_LSHIFT:
        sprinting = False

  if sprinting == True and running == True:
    print("Sprinting")
  elif running == True:
    print("Running")

pygame.quit()
				
			

Test this code and try pressing the “a” key on its own as well as together with “shift” and notice how the output in the console changes.

Using the .key_pressed() function

Depending on the size and complexity of your project and the number of key inputs, you may decide that you want to use an alternative method. And that brings us onto the .key_pressed() function.

Running pygame.key_pressed() will return the state of every key on the keyboard. If a key is being pressed at the time, it will return True, otherwise it will return False.

Since this checks all keystates at once, it will detect multiple key presses, since they will be set to True.

The code for using key inputs this way is shown below. Try pressing different keys and look at the output in the console. The code from above can now be rewritten using this new function. It checks for specific keys and can check for multiple keys at once.

				
					import pygame

pygame.init()

SCREEN_WIDTH = 600
SCREEN_HEIGHT = 400

screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))

run = True
while run:

  key = pygame.key.get_pressed()
  if key[pygame.K_a] == True and key[pygame.K_LSHIFT] == True:
    print("Sprinting")
  elif key[pygame.K_a] == True:
    print("Running")

  for event in pygame.event.get():
    if event.type == pygame.QUIT:
      run = False

pygame.quit()
				
			

This method does simplify keyboard inputs, but there is a caveat in the pygame documentation (see below) that says that this method is not suitable for handling text input from the user so be mindful of this if your game involves the player typing text.

That’s not to say that one method is better than the other, but now that you know the differences, you will be able to pick the one that’s most suitable for your project.

Related Posts

Leave a Reply

Your email address will not be published. Required fields are marked *