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's answerに加えて、2 レベルのマッピング (2 つの辞書) を使用できます

  • キー => コマンド文字列
  • コマンド文字列 => 関数

これにより、ユーザー定義のマッピングを許可しやすくなると思います。つまり、ユーザーは自分のキーを「関数の名前」ではなく「コマンド」にマップできます。

于 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 に答える