Search code examples
pythonpygamekeypresskeydownkeyup

pygame not detecting keypresses


I've been trying to get pygame to detect keypresses so later on I can move a character around on the screen. I'm new to coding so I might just be missing something simple, but I can't figure out what's wrong with the code, should I switch to pygame.key.get_pressed() or something instead? thanks in advance.

running = True
while running: 
    screen.fill((0,0,0))
    # set background
    screen.blit(background, (0,0))
    player(playerX, playerY)
    pygame.display.update()

    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False
        
# detecting key presses
    if event.type == pygame.KEYDOWN:
        if event.type == pygame.K_LEFT:
            print("left")
        if event.type == pygame.K_RIGHT:
            print("right")
        if event.type == pygame.K_UP:
            print("up")
    if event.type == pygame.KEYUP:
        if event.type == pygame.K_LEFT or event.type == pygame.K_RIGHT:
            print("stop")
        pygame.display.update()

Solution

  • It is a matter of Indentation. You must evaluate the events in the event loop instead of the application loop.
    If you want to determine if a certain key is pressed, the you've to verify if the event type is pygame.KEYDOWN (or pygame.KEYUP for button release) and if the .key attribute of the event is equal the key enumerator.

    running = True
    while running: 
        screen.fill((0,0,0))
        # set background
        screen.blit(background, (0,0))
        player(playerX, playerY)
        pygame.display.update()
    
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                running = False
            
        # INDENTATION
        #-->|
            # detecting key presses
            if event.type == pygame.KEYDOWN:
                if event.key == pygame.K_LEFT:  #<-- "key" instead of "type"
                    print("left")
                if event.key == pygame.K_RIGHT: #<-- "key" instead of "type"
                    print("right")
                if event.key == pygame.K_UP:    #<-- "key" instead of "type"
                    print("up")
            if event.type == pygame.KEYUP:
                if event.key == pygame.K_LEFT or event.key == pygame.K_RIGHT: #<-- "key" instead of "type"
                    print("stop")
        #-->|
        # INDENTATION
    

    However, I recommend to use pygame.key.get_pressed() instead of the KEYDOWN event.

    The keyboard events (see pygame.event module) occur only once when the state of a key changes. The KEYDOWN event occurs once every time a key is pressed. KEYUP occurs once every time a key is released. Use the keyboard events for a single action or a step-by-step movement

    pygame.key.get_pressed() returns a sequence with the state of each key. If a key is held down, the state for the key is True, otherwise False. Use pygame.key.get_pressed() to evaluate the current state of a button and get continuous movement.

    clock = pygame.time.Clock()
    velocity = 5
    
    running = True
    while running: 
        clock.tick(60)
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                running = False
            
        keys = pygame.key.get_pressed()
        playerX += (keys[pygame.K_RIGHT] - keys[pygame.K_LEFT]) * velocity
        playerY += (keys[pygame.K_DOWN] - keys[pygame.K_UP]) * velocity
    
        screen.blit(background, (0,0))
        player(playerX, playerY)
        pygame.display.update()