В предыдущих статьях при рассмотрении определенной функции мы подключали к нашей программе дополнительный модуль и наблюдали за изменениями в ее поведении. Теперь отойдем от этой традиции и поработаем с другой простой программой, использующей текстовый интерфейс. Написание обработчика прерывания — операция достаточно сложная и ответственная, ведь при малейшей ошибке ПК может зависнуть. И наконец, коль скоро вам придется работать с клавиатурой «на всю катушку», то, конечно, вы хотели бы иметь программу, позволяющую исследовать поведение этой клавиатуры при различных способах «воздействия».

Текст такой программы приведен в листинге 1. При запуске она установит собственный обработчик клавиатурного прерывания (он находится в блоке инициализации модуля keyboard). Нажатые клавиши будут индицироваться в верхней части экрана, так что понажимайте клавиши и посмотрите, как отреагирует программа. Чтобы выйти из данного режима, следует одновременно нажать и «1». Появится запрос о вводе строки с клавиатуры. Выполните указанное, завершив действия нажатием на , — старый обработчик клавиатурного прерывания будет восстановлен. Затем программа снова установит собственный обработчик, и можно будет опять наблюдать за тем, что происходит при нажатии различных клавиш. По окончании программы стандартный обработчик восстанавливается автоматически. Таким образом, программа будет имитировать какую-либо игровую ситуацию, например временное переключение в режим стандартного ввода для получения, скажем, имени игрока или названия файла для сохранения текущего состояния игры.

Одновременно с этим программа в какой-то мере поможет вам почувствовать свойства всей клавиатуры, поскольку контроллер не опрашивает каждую клавишу поодиночке. Схема клавиатуры представляет собой матрицу, в узлах которой находятся клавиши. На столбцы матрицы контроллер подает сигналы, одновременно следя за информацией в строках. Когда в какой-то из последних появится сигнал, то контроллер зафиксирует нажатие на клавишу. Подобный подход существенно снижает нагрузку на контроллер клавиатуры и упрощает электрическую схему. Однако он имеет и недостаток: не все из нескольких одновременно нажатых клавиш могут быть распознаны. Используйте приведенную выше программу, чтобы проверить это. Обратите внимание, что в зависимости от сочетания максимальное количество распознанных клавиш будет колебаться.

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

Учтите, что даже когда вам удастся найти комбинацию из семи—десяти безошибочно распознаваемых клавиш, то не спешите сразу же применять ее в игре, — какая-нибудь другая клавиатура с этим может и не справиться. Пользуйтесь правилом: «две любые или одна плюс три модификатора». Больше выбирать не стоит, не следует также одновременно нажимать левую и клавиши «курсорного» блока, так как последние могут эмулировать нажатие первой. Если же вы считаете, что четырех одновременно нажатых клавиш для вас мало, то, скорее всего, в игре неправильно рассчитано управление. Так что попытайтесь найти другой вариант, а в крайнем случае пользуйтесь кнопками мыши, только опять же помните, что их иногда бывает всего две.

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

keyboard;{для работы с 
клавиатурой}

Затем сделаем так, чтобы спрайт № 2 управлялся клавиатурой (спрайт № 1 уже «привязан» к мыши). Для этого предусмотрим две переменные, где будем запоминать положение спрайта во избежание его перемещения процедурой CalcSpritePosition.

KbdX,KbdY : word;
{для спрайта, управляе-
мого с клавиатуры}

Кроме того, в основную программу необходимо внести изменения в соответствии с листингом 2. В первую очередь нужно полностью избавиться от вызова стандартных функций работы с клавиатурой: KeyPressed и ReadKey, иначе не избежать зависания компьютера. До сих пор программа завершалась после нажатия любой из клавиш, а сейчас пусть она будет закрываться с помощью .

В основной игровой цикл перед вызовом CalcSpritePosition добавим запоминание координат второго спрайта, а потом изменим его текущие координаты в зависимости от того, какие курсорные клавиши были нажаты. Конечно, можно было бы и не опрашивать текущие координаты при каждом шаге игрового цикла, а один раз определить их в самом начале и затем только вносить коррективы. Но предложенный подход, во-первых, позволяет обойтись лишь временными локальными переменными и, во-вторых, будет очень полезен тогда, когда на координаты спрайта влияют какие-нибудь другие процессы, происходящие в игре, например скроллинг экрана по игровому полю.

Подобно тому, как был выполнен показ нажатия кнопок мыши, реализуем и индикацию клавиш-модификаторов.

Итак, можно считать, что рассмотрены все основные аспекты работы программиста при создании интерфейса игры, т. е. механизма взаимодействия с играющим. Естественно, за бортом оказалась вся внутренняя логика, также включающая немало нюансов, начиная от разработки форматов вспомогательных файлов (уровней, ресурсов или временных записей) и заканчивая искусственным интеллектом. Мы, правда, не уделяли внимания звуку, но на то есть две причины. Одна из них связана с тем, что реализация этой части, вероятно, была бы существенно сложнее, чем остальных. Другая же заключается в том, что используемые приемы вряд ли переносимы на другую платформу. Даже при переходе из реального режима в защищенный звуковую библиотеку пришлось бы переписывать, а при программировании в Windows вообще не понадобятся никакие сведения по программированию DSP (Digital Signal Processor — цифровой сигнальный процессор) или DMAC (КПДП — контроллер прямого доступа к памяти), необходимые для этой работы в DOS. Тем же, кто интересуется данным вопросом, можно порекомендовать некоторые материалы, уже опубликованные в нашем журнале. (См. список литературы. — Прим. ред.)

В заключительных статьях цикла будут рассмотрены особенности использования 32-разрядного защищенного режима процессора, что актуально при работе с более высоким экранным разрешением.

Литература

  1. Солдатенков Д. В. Программируем Sound Blaster // Мир ПК. 1994. № 9.
  2. Андрианов С. А. Программирование Sound Blaster в защищенном режиме процессора // Мир ПК. 1998. № 3.
  3. Андрианов С. А. В обе стороны. О программировании звуковых плат Sound Blaster 16 в режиме full duplex // Мир ПК. 1998. № 11.

Окончание. Начало см.в № 10/02.

1051