В предыдущих статьях при рассмотрении определенной функции мы подключали к нашей программе дополнительный модуль и наблюдали за изменениями в ее поведении. Теперь отойдем от этой традиции и поработаем с другой простой программой, использующей текстовый интерфейс. Написание обработчика прерывания — операция достаточно сложная и ответственная, ведь при малейшей ошибке ПК может зависнуть. И наконец, коль скоро вам придется работать с клавиатурой «на всю катушку», то, конечно, вы хотели бы иметь программу, позволяющую исследовать поведение этой клавиатуры при различных способах «воздействия».
Текст такой программы приведен в листинге 1. При запуске она установит собственный обработчик клавиатурного прерывания (он находится в блоке инициализации модуля keyboard). Нажатые клавиши будут индицироваться в верхней части экрана, так что понажимайте клавиши и посмотрите, как отреагирует программа. Чтобы выйти из данного режима, следует одновременно нажать
Одновременно с этим программа в какой-то мере поможет вам почувствовать свойства всей клавиатуры, поскольку контроллер не опрашивает каждую клавишу поодиночке. Схема клавиатуры представляет собой матрицу, в узлах которой находятся клавиши. На столбцы матрицы контроллер подает сигналы, одновременно следя за информацией в строках. Когда в какой-то из последних появится сигнал, то контроллер зафиксирует нажатие на клавишу. Подобный подход существенно снижает нагрузку на контроллер клавиатуры и упрощает электрическую схему. Однако он имеет и недостаток: не все из нескольких одновременно нажатых клавиш могут быть распознаны. Используйте приведенную выше программу, чтобы проверить это. Обратите внимание, что в зависимости от сочетания максимальное количество распознанных клавиш будет колебаться.
Впрочем, это может привести к неверным выводам. Конструкция клавиатур различных производителей и распознаваемые ими сочетания клавиш могут отличаться, ведь к определению одновременно нажатых клавиш предъявляются не такие уж и строгие требования. Контроллер клавиатуры должен безошибочно распознавать нажатия на любые две клавиши, за исключением двух клавиш модификации, а кроме того, он не различает нажатие на три клавиши модификации, если среди них
Учтите, что даже когда вам удастся найти комбинацию из семи—десяти безошибочно распознаваемых клавиш, то не спешите сразу же применять ее в игре, — какая-нибудь другая клавиатура с этим может и не справиться. Пользуйтесь правилом: «две любые или одна плюс три модификатора». Больше выбирать не стоит, не следует также одновременно нажимать левую
Теперь, когда мы разобрались с работой клавиатуры, пора внести изменения и в нашу основную программу. Сначала, конечно, включим в директиву uses имя нашего нового модуля.
keyboard;{для работы с клавиатурой}
Затем сделаем так, чтобы спрайт № 2 управлялся клавиатурой (спрайт № 1 уже «привязан» к мыши). Для этого предусмотрим две переменные, где будем запоминать положение спрайта во избежание его перемещения процедурой CalcSpritePosition.
KbdX,KbdY : word; {для спрайта, управляе- мого с клавиатуры}
Кроме того, в основную программу необходимо внести изменения в соответствии с листингом 2. В первую очередь нужно полностью избавиться от вызова стандартных функций работы с клавиатурой: KeyPressed и ReadKey, иначе не избежать зависания компьютера. До сих пор программа завершалась после нажатия любой из клавиш, а сейчас пусть она будет закрываться с помощью
В основной игровой цикл перед вызовом CalcSpritePosition добавим запоминание координат второго спрайта, а потом изменим его текущие координаты в зависимости от того, какие курсорные клавиши были нажаты. Конечно, можно было бы и не опрашивать текущие координаты при каждом шаге игрового цикла, а один раз определить их в самом начале и затем только вносить коррективы. Но предложенный подход, во-первых, позволяет обойтись лишь временными локальными переменными и, во-вторых, будет очень полезен тогда, когда на координаты спрайта влияют какие-нибудь другие процессы, происходящие в игре, например скроллинг экрана по игровому полю.
Подобно тому, как был выполнен показ нажатия кнопок мыши, реализуем и индикацию клавиш-модификаторов.
Итак, можно считать, что рассмотрены все основные аспекты работы программиста при создании интерфейса игры, т. е. механизма взаимодействия с играющим. Естественно, за бортом оказалась вся внутренняя логика, также включающая немало нюансов, начиная от разработки форматов вспомогательных файлов (уровней, ресурсов или временных записей) и заканчивая искусственным интеллектом. Мы, правда, не уделяли внимания звуку, но на то есть две причины. Одна из них связана с тем, что реализация этой части, вероятно, была бы существенно сложнее, чем остальных. Другая же заключается в том, что используемые приемы вряд ли переносимы на другую платформу. Даже при переходе из реального режима в защищенный звуковую библиотеку пришлось бы переписывать, а при программировании в Windows вообще не понадобятся никакие сведения по программированию DSP (Digital Signal Processor — цифровой сигнальный процессор) или DMAC (КПДП — контроллер прямого доступа к памяти), необходимые для этой работы в DOS. Тем же, кто интересуется данным вопросом, можно порекомендовать некоторые материалы, уже опубликованные в нашем журнале. (См. список литературы. — Прим. ред.)
В заключительных статьях цикла будут рассмотрены особенности использования 32-разрядного защищенного режима процессора, что актуально при работе с более высоким экранным разрешением.
Литература
- Солдатенков Д. В. Программируем Sound Blaster // Мир ПК. 1994. № 9.
- Андрианов С. А. Программирование Sound Blaster в защищенном режиме процессора // Мир ПК. 1998. № 3.
- Андрианов С. А. В обе стороны. О программировании звуковых плат Sound Blaster 16 в режиме full duplex // Мир ПК. 1998. № 11.
Окончание. Начало см.в № 10/02.