1. Основы терминальных приложений и модуль cmd
Основы терминальных приложений и модуль cmd
Создание интерактивных игр часто ассоциируется с графическими движками, однако фундамент любой игровой логики — это обработка пользовательского ввода. Интерфейс командной строки (CLI) предоставляет идеальную среду для понимания того, как программа принимает команды, обрабатывает их и возвращает результат. Прежде чем переходить к сложным графическим библиотекам, важно освоить текстовый ввод.
Терминальные приложения работают по принципу непрерывного диалога между пользователем и системой. Этот процесс называется REPL.
> REPL (Read-Eval-Print Loop) — это интерактивная среда, которая читает ввод пользователя, вычисляет (обрабатывает) его, печатает результат и возвращается в состояние ожидания новой команды.
Текстовые игры и терминальные приложения невероятно эффективны. Терминальные приложения потребляют в среднем на 80 процентов меньше оперативной памяти, чем их графические аналоги. Если базовая игра с графическим интерфейсом требует минимум 50 мегабайт памяти, то текстовый квест обойдется всего в 10 мегабайт, что делает их отличным выбором для прототипирования.
Анатомия интерактивного цикла
Самый простой способ создать терминальную игру — использовать бесконечный цикл while и встроенную функцию input(). Пользователь вводит текст, программа проверяет его через цепочку условий и выдает ответ.
Этот подход работает для простых скриптов, но при создании полноценной игры с десятками команд код быстро превратится в нечитаемую стену из if и elif. Кроме того, разработчику придется самостоятельно писать логику для обработки аргументов (например, "идти на север"), создания меню помощи и обработки ошибок ввода.
В играх часто возникает необходимость вычислять дистанцию между сущностями. Для этого применяется теорема Пифагора: , где — искомое расстояние, — разница координат по оси X, а — разница координат по оси Y. Если игрок находится в точке (0, 0), а враг в точке (3, 4), то расстояние составит 5 единиц. Обработка таких команд вручную через input() усложняет архитектуру.
Встроенный модуль cmd
Для решения проблемы масштабируемости в стандартной библиотеке Python существует модуль cmd. Он предоставляет готовую объектно-ориентированную структуру для создания строчно-ориентированных интерпретаторов.
Чтобы превратить обычный скрипт в мощное терминальное приложение, нужно выполнить несколько шагов:
cmd.cmd.Cmd.do_.cmdloop() для запуска приложения.Любой метод, начинающийся с do_, автоматически становится доступной командой в вашем терминале. Если вы назовете метод do_attack, пользователь сможет ввести слово attack, и программа выполнит соответствующий код.
| Характеристика | Цикл while + input() | Модуль cmd.Cmd | |---|---|---| | Масштабируемость | Низкая (много if/elif) | Высокая (каждая команда — отдельный метод) | | Справка (Help) | Нужно писать вручную | Генерируется автоматически | | Автодополнение | Отсутствует | Поддерживается (клавиша Tab) | | Обработка аргументов | Ручной парсинг строки | Аргументы передаются в метод автоматически |
Создание игрового лобби
Рассмотрим, как модуль cmd применяется на практике при создании текстовой ролевой игры. Нам нужно создать лобби, где игрок может осмотреться, проверить инвентарь или выйти из игры.
В классе Cmd есть два важных атрибута, которые позволяют кастомизировать внешний вид терминала:
* intro — текст, который выводится один раз при запуске программы (приветствие).
* prompt — строка приглашения ко вводу, которая отображается перед курсором.
Обратите внимание на метод do_quit. Он возвращает логическое значение True. В архитектуре модуля cmd возвращение истины из метода команды сигнализирует циклу cmdloop() о том, что работу интерпретатора необходимо завершить. Если метод не возвращает ничего (или возвращает False), цикл продолжает запрашивать новые команды.
В играх важна математика характеристик. Урон = Базовая атака * Множитель оружия. При базовой атаке 15 и множителе стального меча 1.5, итоговый урон составит 22.5 единиц. Всю эту логику можно инкапсулировать внутри конкретного метода do_attack, не засоряя глобальную область видимости.
Обработка аргументов и встроенная справка
Каждый метод do_ принимает параметр arg. Это строка, содержащая всё, что пользователь ввел после названия команды.
> Если пользователь вводит команду take sword, система вызывает метод do_take(self, arg), где переменная arg будет содержать строку "sword".
Это позволяет создавать гибкие команды. Разработчику остается лишь разбить строку arg на части (например, с помощью метода split()), если команда требует нескольких параметров.
Еще одна мощная функция модуля — автоматическая генерация документации. Если в запущенном приложении ввести команду help, система выведет список всех доступных команд (всех методов с префиксом do_). Если ввести help look, терминал напечатает строку документации (docstring), которую мы указали внутри метода do_look. Это избавляет от необходимости писать отдельные громоздкие функции для обучения игрока управлению.
Использование объектно-ориентированного подхода позволяет легко сохранять состояние игры. Атрибуты класса (например, self.hp или self.inventory) будут доступны в любом методе команды, обеспечивая связность данных на протяжении всей игровой сессии. Если переменная здоровья , где — текущее здоровье игрока, можно принудительно вызвать завершение цикла, имитируя конец игры.