Обработка нажатий клавиш: пытаемся управлять

Обработка нажатий клавиш: пытаемся управлять

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

Обработка событий пользовательского ввода в RRS устроена достаточно мудрено из-за того что визуализация и прием событий с устройств ввода работает в отдельном от симуляции движения поезда процессе. Не вдаваясь глубоко в механику данного процесса могу сказать только, что получение состояния клавиатуры реализована достаточно прозрачно для разработчика.

Для начала переопределим в нашем классе SimpleLoco метод keysProcess()

В файле simple-loco.cpp описываем реализацию этого метода

Метод keyProcess() вызывается симулятором периодически. Реализовав в нем процесс обработки клавиш, можно добиться реакции дополнение на прикладываемые управляющие сигналы. Вопрос только в том, как отслеживать состояние клавиш.

Для этой цели базовый класс Vehicle предоставляет ряд методов

  • bool getKeyState(int key) — возвращает состояние клавиши (нажата или отпущена) по переданному в качестве параметра коду клавиши;
  • bool isShift() — возвращает истину, если нажат хотя бы один Shift
  • bool isControl() — возвращает истину, если нажат хотя бы один Control;
  • bool isAlt() — возвращает истину, если нажат хотя бы один Alt

Коды клавиш задаются с помощью перечислителей, определенных в файле sdk/include/key-symbols.h. Остается только определится с тем, что мы в первую очередь реализуем в нашем учебном проекте.

Отставив в сторону реализм, сделаем простейшую операцию — по нажатию клавиш A и D сделаем увеличение и уменьшение, соотвественно, уровня заданного тягового усилия. Для этого заведем в классе переменную, которая будет хранить этот уровень

Обязательно (!) инициализируем эту переменную в конструкторе класса

C++ это язык в котором очень легко, что называется, «выстрелить себе в ногу». Если в коде существует переменная, значение которой изначально не задано, это может привести к неопределенному поведению программы. Поэтому возьмем за правило инициализировать все вводимые переменные, особенно локальные, как в данном случае.

Теперь мы можем работать с этой переменной, напишем в методе keyProcess() следующий код

Все очень просто — по нажатию клавиши A заданный уровень тяги увеличивается, по нажатию клавиши D — уменьшается.

Отдельно следует упомянуть вызов функции cut(). Эта функция описана в модуле physics.dll и является шаблонной. Ее назначение — ограничивать подаваемое на вход значение заданными пределами. Прототип этой функции выглядит так

функция возвращает x, если он находится в пределах от min до max, возвращает min если x меньше минимального значения, и max — если x больше максимального. Таким образом, в приведенном коде мы «обрезаем» значение уровня заданной тяги в пределах от 0 до 1. Ведь если мы не сделаем этого, то при долгом удержании клавиши A уровень может дорасти и до 10, и до 100 и до 1000, что нас не устраивает по понятным причинам.

После компиляции и запуска локомотива все это будет происходить, но каким образом мы сможем отследить правильную работу кода? Познакомимся с ещё одним важным инструментом разработчика — отладочной строкой. Эта строка записывается в стандартную переменную класса Vehicle, названную DebugMsg. Допишем в функцию-обработчик клавиш еще немного кода

Как мы можем увидеть эту отладочную информацию? Для этого запускаем симулятор, жмем F1 и видим внизу экрана эту самую строку, где отображается уровень заданной тяги

Нажимая клавиши мы увидим, что переменная таки действительно изменяется, что не может нас не радовать, ведь мы освоили еще одну базовую возможность API RRS.

Ну так и что, скажете вы, заданная тяга растет, а локомотив не едет. Как добиться того, чтобы он поехал — об этом мы поговорим дальше.

Назад Вперед
Содержание