如何正确使用`sdl2.SDL_GetKeyboardState`?

How can `sdl2.SDL_GetKeyboardState` be used correctly?

我正在尝试使用 python 库 pysdl2 构建模拟器。到目前为止,该库运行良好,但我在接收键盘输入时遇到了问题。

我基本上需要做的是测试是否按下了某些键。在做了一些研究之后,我发现 sdl2.SDL_GetKeyboardState 据说与 SDL_GetKeyboardState. Following the previously linked documentation and this article on the Lazy Foo' Productions website 是相同的 SDL 函数,我构建了以下脚本:

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()

上面的代码假设检测​​ a 键是否被按下,如果是则打印一条消息。当上面的程序是运行的时候,确实出现了一个window,但是当按下a键的时候,却打印了'A key pressed'四千多次。它不会继续打印消息,它只打印一次数千次,然后停止。

起初,我认为问题可能在于关键推导代码(第 15-16 行)应该在事件循环(第 11-14 行)内部。它在某种程度上起作用了。 'A key pressed' 不是每次按键打印数千次,而是每次按键只打印两次。

我的代码有问题吗?我是否缺少有关如何正确使用 sdl2.SDL_GetKeyboardState 函数的信息?如何正确检测按键?

听起来它正在按照预期的方式工作。只要按下 akey_states[sdl2.SDL_SCANCODE_A] 就会 return 为真。循环中没有太多处理,所以它会以 CPU 允许的速度循环,每秒打印 "A key pressed" 数百或数千次,直到你释放键。

您可以检查不同的事件类型,例如 SDL_KEYDOWN,它的运行方式更像您想要的,或者您可以使用变量跟踪按键,例如:

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()