7

我在 Mac OS X 10.6 上,我的键盘输入选择器菜单中有 Dvorak、US Extended 和挪威语,而我使用的是 US Extended。

当我使用键盘输入运行 Pygame 程序时,pygame 似乎认为我正在使用 dvorak ,而不管实际选择了什么。

这是接受键盘输入的代码部分:

    # Check for events
for event in pygame.event.get():
    if event.type == KEYDOWN:
        # Change the keyboard variables
        if event.key == K_LEFT or event.key == ord('a'):
            moveRight = False
            moveLeft = True
        if event.key == K_RIGHT or event.key == ord('d'):
            moveLeft = False
            moveRight = True
        if event.key == K_UP or event.key == ord('w'):
            moveDown = False
            moveUp = True
        if event.key == K_DOWN or event.key == ord('s'):
            moveUp = False
            moveDown = True
    if event.type == KEYUP:
        if event.key == K_ESCAPE:
            pygame.quit()
            sys.exit()
        if event.key == K_LEFT or event.key == ord('a'):
            moveLeft = False
        if event.key == K_RIGHT or event.key == ord('d'):
            moveRight = False
        if event.key == K_UP or event.key == ord('w'):
            moveUp = False
        if event.key == K_DOWN or event.key == ord('s'):
            moveDown = False
        if event.key == ord('x'):
            player.top = random.randint(0, WINDOWHEIGHT - player.height)
            player.left = random.randint(0, WINDOWWIDTH - player.width)

箭头键可以正常工作,但 WASD 键以与 Dvorak 一致的方式分布在键盘上。因此,“A”在两个布局上的位置相同,“W”在 QWERTY 的逗号键上,依此类推。如果我更改代码以查找a、和键e,则事情会按预期工作。,o

如何让 Pygame 使用正确的布局?

4

2 回答 2

2

好吧,我不得不做一些杂技来让它工作。因此,首先我建议您使用可以从中获取的密钥扫描码event.scancode。每个键都有一个唯一的代码,它指的是键盘上的物理键,无论您的键盘布局 dvorak 还是我们,这都是相同的扫描码。然后在 keydown 事件上,您将有一个名为 unicode 的属性,它是尊重当前使用的键盘布局的按下字符。因此,在 us 布局上按 d 键可以获得 unicode d,在 dvorak 上,物理键会为您提供 e 字符,这会正确反映在event.unicode. 这就是它变得有点烦人的地方。似乎 unicode 属性仅适用于 keydown 事件,而不适用于 keyup 事件。因此,我简单地创建了一个名为 keymap 的字典,将这些信息作为扫描码到 unicode 字符的映射来跟踪。下面的示例代码将根据键盘布局打印出您按下的字符。您可以尝试一下,即使您在程序执行期间切换键盘布局,它仍然会选择正确的键。您在下面看到的输出是我在我们的布局中按下 d 键切换到 dvorak 按下相同的键并正确得到 e 的会话。向你致敬,因为使用 dvorak 的方式比 qwerty 更好,我也使用它 :)

代码

import pygame, os
from pygame.locals import *

pygame.init()
screen = pygame.display.set_mode((640, 480))
keymap = {}

while True:
    event = pygame.event.wait()
    if event.type == KEYDOWN:
        keymap[event.scancode] = event.unicode
        print 'keydown %s pressed' % event.unicode
        if (event.key == K_ESCAPE):
            os._exit(0)

    if event.type == KEYUP:
        print 'keyup %s pressed' % keymap[event.scancode]

输出

keydown d pressed
keyup d pressed
keydown e pressed
keyup e pressed
于 2012-11-23T15:27:02.800 回答
0

接受的答案是正确的,但为了简洁起见,这里是解决方案:

if event.type == pygame.KEYDOWN:
   print(event.unicode)
于 2020-05-26T17:26:16.033 回答