【问题标题】:Pygame keyboard layouts mixed upPygame 键盘布局混淆
【发布时间】:2012-11-11 19:27:38
【问题描述】:

我使用的是 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 的逗号键上,依此类推。如果我更改代码以查找 ae,o 键,则一切正常。

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

【问题讨论】:

  • 你为什么使用 ord() 而不是 pygame 给出的 KEYS?
  • 代码来自 Invent Your Own Computer Games with Python 一书。 (inventwithpython.com) 我不知道作者为什么选择 ord() 而不是 KEYS。我可能会在下一章或续集 Invent [...] with Pygame 中了解这一点。
  • 不好意思,续集其实叫《用 Python & Pygame 制作游戏》

标签: python pygame keyboard-events dvorak


【解决方案1】:

好吧,我必须做一些杂技才能让它发挥作用。所以首先我建议你使用key scancode,你可以从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

【讨论】:

  • 谢谢!这个解决方案效果很好!不过,我仍然想知道为什么 pygame 默认不读取当前的键盘布局。
  • 在某种程度上,它为您提供物理按键和布局字符。以这种方式实现它可能是一个设计决定。不过这很令人困惑。
【解决方案2】:

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

if event.type == pygame.KEYDOWN:
   print(event.unicode)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-07-21
    • 2010-11-19
    • 1970-01-01
    • 2015-01-06
    • 1970-01-01
    相关资源
    最近更新 更多