ozu
ozu

Reputation: 23

How to delay pygame.key.get_pressed()?

I haven't been able to find a straightforward answer.

key.set_repeat() works for KEYDOWN events, but not for key.get_pressed():

import sys, pygame
from pygame.locals import *

pygame.init()
Clock = pygame.time.Clock()
pygame.display.set_mode((200, 100))

pygame.key.set_repeat(1, 500)

while True:

    if pygame.key.get_pressed()[K_UP]:
        print('up!')

    for event in pygame.event.get():

        if event.type == QUIT:
            pygame.quit()
            sys.exit()

        elif event.type == KEYDOWN:
            if event.key == K_DOWN:
                print('down!')

    Clock.tick(30)

Even the slightest tap on UP explodes into at least a few up!s, only down!s are delayed. I want to use key.get_pressed() since it conveniently handles multiple inputs. Do I have to work around it with some sorta tick counter? Alternatively, is there a way to handle multiple KEYDOWN events?

Upvotes: 0

Views: 2148

Answers (1)

sloth
sloth

Reputation: 101162

Just don't mess around with key.set_repeat() if you don't have to.

Simply use key.get_pressed() to check for keys that are pressed and where keeping that key pressed down has a meaning to you, e.g. something like move left while K_LEFT is pressed.

Use event.get() / KEYDOWN when you're interessed in a single key press, e.g. something like pressing K_P pauses the game.

If you mess around with key.set_repeat(), e.g. set the delay to low, you won't be able to recognize a single key stroke, since every key stroke will create multiple KEYDOWN events.

To handle multiple KEYDOWN events, just check for the relevant events. Every key stroke will generate a KEYDOWN event, so you can simple check e.g.:

for event in pygame.event.get():
    if event.type == KEYDOWN:
        if event.key == K_DOWN:
            print('down!')
        elif event.key == K_UP:
            print('up!')

That will of course print up!/down! multiple times if the user keeps pressing the keys.

The golden rule is: If you're interessted in the KEYDOWN and the KEYUP event of a single key, better use key.get_pressed() instead.


Even the slightest tap on UP explodes into at least a few up!s, only down!s are delayed

That's because the event system and key.get_pressed() are totally different. If you get pressing K_UP over multiple frames, for each frame 'up!' is printed because the key is pressed down in every frame. key.get_pressed() simple returns which keys are pressed at the moment you call this function. In other words: you can't "delay" it.

Upvotes: 1

Related Questions