Можно ли использовать getch() для получения входных данных различной длины?

Я взялся за приключение по созданию сравнительно небольшой RPG для командной строки, чтобы напрячь мои вновь обретенные мускулы Python, но я уже столкнулся с головоломкой. Я использую эту реализацию getch():

def getch():
    fd = sys.stdin.fileno()
    old_settings = termios.tcgetattr(fd)
    tty.setraw(sys.stdin.fileno())
    key = sys.stdin.read(3)
    termios.tcsetattr(fd, termios.TCSADRAIN, old_settings)

я имею key установите для чтения в 3 символа, чтобы захватить клавиши со стрелками. Up, например, читается как ESC[A; с этим методом я могу использовать key[2] определить, была ли нажата стрелка и какая. Все хорошо, за исключением того, что я также хотел бы захватывать все виды других ключей; q для журнала квестов, wasd для передвижения (нажатие стрелок в разных порядках будет методом атаки) и многие другие. Проблема сразу проясняется; если getch() возвращает только один символ, функциональность стрелки полностью теряется.

Я обдумываю переосмысление системы стрелок, если нет простого решения, но я почти уверен, что так и должно быть. Правда, я мало что знаю о том, что происходит внутри tty, но я где-то читал, что если вы читаете только в 1 символе, лишние символы от нажатия стрелки остаются в буфере. Как я могу получить доступ к указанному буферу? В качестве альтернативы, есть какой-то умный способ сказать stdin ожидать ввода переменной длины?

Заранее спасибо за любую помощь.

2 ответа

Решение

Не читайте три символа. Прочитайте один.

Если один символ, который вы только что прочитали ESC, прочитайте другой символ или два, чтобы видеть, была ли это клавиша со стрелкой или что-то еще. Если бы это было q, сделай вещь для этого и затем начни сначала.

Если вы подумываете о разработке полной игры, PyGame также может быть полезным ncurses).

getch() Фрагмент может быть обновлен для чтения клавиши со стрелкой, но как сделать различие между первым символом клавиши со стрелкой и ESC ключ? Если пользователь нажмет ESCописанное решение, вероятно, будет ожидать следующего нажатия клавиши.

Я не нашел никакого решения для обработки этого последнего случая.

Другие вопросы по тегам