pythonsdl-2keyboard-inputpysdl2

How can `sdl2.SDL_GetKeyboardState` be used correctly?


I'm attempting to use the python library pysdl2 to construct an emulator. The library has been working well so far, however I've been having problems receiving keyboard input.

What I essentially needed to do is test if certain keys are pressed. After doing a bit of research, I discovered sdl2.SDL_GetKeyboardState which supposedly is the same SDL function as SDL_GetKeyboardState. Following the previously linked documentation and this article on the Lazy Foo' Productions website, I constructed the following script:

import sdl2
sdl2.ext.init()

window = sdl2.ext.Window('Test', size=(640, 480))
window.show()

key_states = sdl2.SDL_GetKeyboardState(None)
running = True

while running:
    for event in sdl2.ext.get_events():
        if event.type == sdl2.SDL_QUIT:
            running = False
            break
    if key_states[sdl2.SDL_SCANCODE_A]:
        print('A key pressed')
    window.refresh()

The above code is suppose to detect if the a key is pressed and if so print a message out. When the above program is run, a window does appear, but when the a key is pressed, 'A key pressed' is printed over four thousand times. It does not continue to print the message, it only prints it once thousands of times, then stops.

At first, I consider that the problem may have been that the key deduction code (lines 15-16) should be inside of the the event loop (lines 11-14). It worked to some degree. Rather than 'A key pressed' being printed out thousands of times per key press, it was only being printed out twice per key press.

Is there a problem with my code? Am I missing something about how to correctly use the sdl2.SDL_GetKeyboardState function? How can I properly detect key presses?


Solution

  • Sounds like it's working the way it's supposed to. key_states[sdl2.SDL_SCANCODE_A] will return true whenever a is pressed. And there's not much processing going on in your loop, so it'll loop as fast as your CPU allows, printing out "A key pressed" hundreds or thousands of times per second, until you release the key.

    You could check for a different event type, such as SDL_KEYDOWN, which operates more like how you're wanting, or you can keep track of the keypress with a variable, for example:

    key_down = False
    while running:
        for event in sdl2.ext.get_events():
            if event.type == sdl2.SDL_QUIT:
                running = False
                break
        if key_states[sdl2.SDL_SCANCODE_A] and not key_down:
            print('A key pressed')
            key_down = True
        elif not key_states[sdl2.SDL_SCANCODE_A] and key_down:
            print('A key released')
            key_down = False
        window.refresh()