Вопрос

Каков хороший способ реализовать обработку клавиатуры?На любом языке, где я пишу интерактивную с клавиатуры программу (например, игру тетрис), я получаю код, который выглядит следующим образом:

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)

(сокращенно).Мне это не нравится, так как это должно происходить в моем основном цикле и портит все части программы.Это также делает невозможным создание экрана конфигурации пользователя, на котором они могут изменить, какие клавиши соответствуют каким действиям.Есть ли хороший шаблон для этого, используя ту или иную форму обратных вызовов функций?

Это было полезно?

Решение

Вы можете создать словарь, в котором ключи являются входными данными, а значение — функцией, обрабатывающей нажатие клавиш:

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

Тогда изменение ключей — это вопрос изменения ключей словаря.

Другие советы

в дополнение к ответ superjoe30, вы можете использовать два уровня сопоставления (два словаря)

  • ключ => командная строка
  • командная строка => функция

Я думаю, что это облегчит разрешение пользовательских сопоставлений.то естьчтобы пользователи могли сопоставлять свои клавиши с «командами», а не с «именем функции».

Сейчас у меня есть какой-то класс/функция/поток сбора входных данных, который будет проверять список предопределенных привязок клавиш->событий.

Что-то вроде этого:

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, за исключением того, что вместо прямого вызова обратных вызовов я добавляю еще один уровень разделения, используя систему диспетчеризации событий, так что любой код, который заботится о нажатии клавиш, просто прослушивает это событие.

Кроме того, ключи можно легко привязать к различным событиям, которые можно прочитать из файла конфигурации или чего-то еще, а любой ключ, не привязанный к событию, просто игнорируется.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top