pygame Event handling State checking


It's possible to call functions from the pygame.key and pygame.mouse module to receive the state of the key and mouse. However, it's not the recommended way to process events in pygame since there are some flaws with it:

  • You'll receive the states when the function is called, which means you might miss events between calls if the user is pressing buttons fast.

  • You cannot determine the order of the events,.

  • You still need to to call one of pygame's event functions for pygame to internally interact with the operating system, otherwise it'll warn that program has become unresponsive. The functions you can call are:

    • pygame.event.get() to get all events or event types (by passing the types as an argument) from the queue.
    • pygame.event.poll() to get one single event from the queue.
    • pygame.event.wait() to wait for one single event from the queue.
    • pygame.event.clear() to clear all events in the queue.
    • pygame.event.pump() to allow pygame to handle internal actions (is called implicitly by the functions above).

Keyboard events

The key module has a function pygame.key.get_pressed() which returns a list of the state of all keys. The list contains 0 for all the keys which are not pressed and 1 for all keys that are pressed. Its index in the list is defined by constants in the pygame module, all prefixed with K_ and the key name.

pygame.event.pump()  # Allow pygame to handle internal actions.
key = pygame.key.get_pressed()
if key[pygame.K_a]:
    print("You pressed 'a'")
if key[pygame.K_F1]:
    print("You pressed 'F1'")
if key[pygame.K_LSHIFT]:
    print("You pressed 'left shift'")
if key[pygame.K_q]:  # Press 'q' to exit the program

If you want to check for a single key press instead of if the key is held down, you can store the previous state of all keys in a temporary variable and check if the value changes:

pygame.event.pump()  # Allow pygame to handle internal actions.
key = pygame.key.get_pressed()
if key[pygame.K_q] and not previous_key[pygame.K_q]:
    print("You pressed 'q'")
if key[pygame.K_p] and not previous_key[pygame.K_p]:
    print("You pressed 'p'")
previous_key = key

The statement evaluates to true only when the current key is pressed down and the previous key isn't pressed down. To check whether the user released the key you only have to switch the not keyword (if not key[pygame.K_q] and previous_key[pygame.K_q]). For this to work properly, you have to set the variable previous_key = pygame.key.get_pressed() before the game loop, otherwise you'll receive a NameError.

Mouse events

The mouse module has functions that lets us check and set the position of the mouse as well as check the buttons pressed. The function pygame.mouse.get_pressed() returns a tuple tuple representing if the mouse buttons (left, mouse-wheel, right) is being pressed or not.

pygame.event.pump()  # Allow pygame to handle internal actions.
mouse_pos = pygame.mouse.get_pos()
mouse_buttons = pygame.mouse.get_pressed()
if mouse_pos[0] > 100:
    pygame.mouse.set_pos(10, mouse_pos[1])  # Reset the mouse's x-position to 10.
    print("YOU SHALL NOT PASS!")
if mouse_buttons[2]:
    print("I'm right, right?")
if mouse_buttons[0]:  # Press left mouse button to exit.
    print("Program left")