0
votes

The pygame.key.get_pressed() function seems not to be working as expected on my Mac OSX (10.11.1) using Python 3 and Pygame.

After importing pygame and the time module I check if the w key (pygame.K_w) is pressed by using a simple if-statement and Pygames pygame.key.get_pressed() function.

But the test fails and It didn't work is printed very time:

#!/usr/bin/env python3
import pygame, time
pygame.init()

while True:
    keypressed = pygame.key.get_pressed()

    time.sleep(5)
    print("5 seconds later")

    if keypressed[pygame.K_w]:
         print("it worked")
    else: 
         print("It didn't work")
2
how is it not working? - Anthony

2 Answers

4
votes

The first problem is that you don“t actually create a Pygame window. Use the pygame.display.set_mode() function to initialize a window or screen for displaying. Normally this is done before calling the main event loop in a Pygame program:

import pygame
pygame.init()

#initialize a display with 100 x 100 pix resolution  
display = pygame.display.set_mode((100,100))

while True:
    #some code

Because you are not using any event functions in your main game loop, Pygame can not handle internal actions, such as key state information information. To avoid this you should call pygame.event.pump() inside the event loop:

while True:
    #internally process pygame event handlers
    pygame.event.pump()
    keypressed = pygame.key.get_pressed()

    time.sleep(5)
    print("5 seconds later")

    if keypressed[pygame.K_w]:
        print("it worked")
    else: 
        print("It didn't work")

Now your program should recognize pygame.K_w key actions, but only every 5 seconds since you sleep the game using Pythons time.sleep() function.

Because this isn't really a good practice there are a number of solutions to avoid this problem. You could:

  • call instead of the pygame.event.pump() function pygame.event.wait() to wait for an event and sleep the game when no events are happening:

    import pygame
    pygame.init()
    
    display = pygame.display.set_mode((100,100))
    
    while True:
        #wait for a single event from the queue
        pygame.event.wait()
        keypressed = pygame.key.get_pressed()
    
        if keypressed[pygame.K_w]:
            print("it worked")
        else: 
            print("It didn't work")
    
  • use a pygame.time.Clock object to set a framerate for your program:

    import pygame
    pygame.init()
    
    display = pygame.display.set_mode((100,100))
    
    clock = pygame.time.Clock()
    
    while True:
        pygame.event.pump()
        keypressed = pygame.key.get_pressed()
    
        if keypressed[pygame.K_w]:
            print("it worked")
        else: 
            print("It didn't work")
    
        #compute how many milliseconds have passed since the previous call
        clock.tick(30)
    
1
votes

First of all, you should initialize your pygame window, then call your function that will process all your events (like waiting for a key to get pressed and reacting to it after that).

import pygame
pygame.init()
screensize = (100, 100) #choose the size, in pixels.
window = pygame.display.set_mode(screensize) #Initialize your pygame window!
gameloop()

Your game loop is a function that looks like this:

while not finished:
    finished = doStuff() #returns True if the game should end.
pygame.quit()

The variable 'finished' is supposed to let the program know when it is supposed to end, for example, after pressing the 'X' in the top-right corner of the window. Inside this function, we will listen to all the events, such as pressing a Key, releasing it, holding it and so on.

def doStuff():
    events = pygame.event.get() #Use this function to get all the events that happened, then iterate through it.
    finished = False
    for event in events:
        if event.type == pygame.KEYDOWN and event.key == pygame.K_w:
            print("It worked!")
        if event.type == pygame.QUIT:
            final = True
        else:
            print("It didn't work")
        #more events here
    return finished