9

什么是实现键盘处理的好方法?在我编写键盘交互程序(例如俄罗斯方块游戏)的任何语言中,我最终都会得到一些如下所示的代码:

for event in pygame.event.get():
    if event.type == KEYDOWN:
        if False: pass          #make everything an elif
        elif rotating: pass
        elif event.key == K_q:
        elif event.key == K_e:
        elif event.key == K_LEFT:
            curpiece.shift(-1, 0)
            shadowpiece = curpiece.clone(); setupshadow(shadowpiece)
        elif event.key == K_RIGHT:
            curpiece.shift(1, 0)
            shadowpiece = curpiece.clone(); setupshadow(shadowpiece)

(缩短)。我不喜欢这样,因为它必须进入我的主循环,并且它与程序的所有部分都混淆了。这也使得不可能有一个用户配置屏幕,他们可以在其中更改哪些键映射到哪些操作。有没有使用某种形式的函数回调来做到这一点的好模式?

4

3 回答 3

17

您可以创建一个字典,其中键是输入,值是处理按键的函数:

def handle_quit():
  quit()

def handle_left():
    curpiece.shift(-1, 0)
    shadowpiece = curpiece.clone(); setupshadow(shadowpiece)

def handle_right():
    curpiece.shift(1, 0)
    shadowpiece = curpiece.clone(); setupshadow(shadowpiece)

def handle_pause():
    if not paused:
        paused = True

branch = {
  K_q: handle_quit
  K_e: handle_pause
  K_LEFT: handle_left
  K_RIGHT: handle_right
}

for event in pygame.event.get():
    if event.type == KEYDOWN:
        branch[event.key]()

然后更改键是修改字典键的问题。

于 2008-11-23T07:32:57.723 回答
3

除了superjoe30的回答,还可以使用两级映射(两本词典)

  • 键 => 命令字符串
  • 命令字符串 => 函数

我认为这将使允许用户定义的映射更容易。也就是说,用户可以将他们的键映射到“命令”而不是“函数的名称”

于 2008-11-23T20:03:50.483 回答
2

我现在做的是有某种输入收集类/函数/线程,它将检查预定义的键->事件绑定列表。

像这样的东西:

class InputHandler:
    def __init__ (self, eventDispatcher):
        self.keys = {}
        self.eventDispatcher = eventDispatcher
    def add_key_binding (self, key, event):
        self.keys.update((key, event,))
    def gather_input (self):
        for event in pygame.event.get():
            if event.type == KEYDOWN:
                event = self.keys.get(event.key, None)
                if not event is None:
                    self.eventDispatcher.dispatch(event)

....
inputHandler = InputHandler(EventDispatcher)
inputHandler.add_key_binding(K_q, "quit_event")
...
inputHandler.gather_input()
....

这基本上就是 superjoe30 正在做的事情,只是我没有直接调用回调,而是通过使用事件调度系统添加了另一个级别的分离,以便任何关心被按下的键的代码都只需侦听该事件。

此外,键可以轻松绑定到不同的事件,可以从配置文件或其他内容中读取,并且任何未绑定到事件的键都将被忽略。

于 2008-11-24T12:05:58.793 回答