Можно ли использовать 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 символах, чтобы захватить клавиши стрелки. Вверх, например, читается как ESC[A
; С помощью этого метода я могу использовать key[2]
Чтобы определить, была ли нажата клавиша стрелки, а какой. Все хорошо, за исключением того, что я также хотел бы запечатлеть все виды других ключей; q
для журнала квестов, wasd
Для движения (нажатие стрел в различных порядках будет методом атаки) и многими другими. Проблема мгновенно ясна; если getch()
Возвращает только один символ, функциональность стрелки теряется полностью.
Я вообще обдумываю переосмысление системы стрел, если нет простого решения, но я почти уверен, что это должно быть. По общему признанию, я мало знаю о том, что происходит внутри tty
, но я где -то читал, что если вы читаете только в 1 символе, избыточные символы из пресса стрелки сохраняются в буфере. Как я могу получить доступ к указанному буферу? В качестве альтернативы, есть ли какой -то умный способ сказать stdin
ожидать ввода переменной длины?
Заранее спасибо за любую помощь.
Решение
Не читайте три символа. Прочитайте один.
Если один персонаж, которого вы только что прочитали ESC
, Прочитайте другой или два персонажа, чтобы увидеть, был ли это ключом стрелы или что -то еще. Если это было q
, сделайте это для этого, а затем начните все сначала.
Другие советы
Если вы рассмотрите возможность разработки полной игры, PyGame
также может быть полезен (в конце концов ncurses
).
А getch()
фрагмент можно обновить, чтобы прочитать ключ стрелы, но как изменить разницу между первым символом клавиши стрелы и ESC
ключ? Если пользователь нажимает ESC
, Описанное решение, вероятно, будет ждать следующего нажатия клавиши.
Я не нашел никакого решения для обращения с этим последним случаем.