Содержание статьи
- Подготовка
- (Пере)запускаем игру
- Начинаем игровой цикл: высчитываем координаты птицы и рисуем ее
- Продолжаем игровой цикл: смотрим, нет ли столкновений
- Завершаем игровой цикл: проверяем, не встретилась ли на пути труба
- DelayBeforeCadr: делаем задержку
- MoveScene: перерисовываем игровое поле
- MoveScene: рисуем трубу
- Сигнатура загрузочного сектора
Да, затолкать что-то вразумительное в 512 байт загрузочного сектора — та еще задачка. Бутсекторная программа выполняется до запуска операционной системы, а значит, функции ОС ей недоступны.
Даже для такого, казалось бы, простого действия, как вывести число на экран, придется писать свою собственную подпрограмму. Кроме того, забудь о высоком разрешении экрана, простом и удобном доступе к GPU и звуковой карте. А еще учти, что BIOS, выполняя бутсекторную программу, смотрит на процессор твоего Ryzen или Core i9 как на примитивный 16-битный 8088.
Вводные не очень-то обнадеживают! Но базовые функции BIOS у нас никто не отнимал. Мы можем выводить текст, рисовать крупноразмерные пиксели, читать системный таймер, следить за клавиатурой. Этого вполне хватит для несложной игрушки!
На случай, если ты пропустил шумиху в 2013 году, поясню смысл игры. Летящая слева направо по экрану птаха должна облетать торчащие снизу и сверху экрана трубы. Если игрок ничего не делает, она самопроизвольно снижается. Нажатие на кнопку заставляет ее взмахнуть крыльями и немного подняться вверх. Секрет в том, чтобы соблюдать нужный ритм и не врезаться. Вот и вся игруха.
А теперь возьмемся за реализацию!
Подготовка
Говорим компилятору, что наша программа 16-битная, резервируем несколько ячеек памяти под переменные, прыгаем на точку входа. Обрати внимание, что мы здесь не создаем переменные, не выделяем для них память, а просто задаем мнемонику для ячеек памяти, которые уже существуют.

Делаем еще несколько подготовительных телодвижений:
- переходим в текстовый режим 25 × 80 и очищаем экран;
- сбрасываем «флаг направления», чтобы строки обрабатывались слева направо, а не наоборот (когда будем обращаться к инструкциям вроде stosw);
- сегментные регистры нацеливаем на область оперативной памяти, которая отображена на видеопамять. Так нам будет удобней отрисовывать игровое поле.

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

Надо дать игроку успеть приноровиться к управлению, поэтому первую трубу отрисовываем только после 160-го кадра. В next
запишем число 160 (0xA0
) и пишем не mov ax, 0x00A0
, а mov al, 0xA0
. Нам, конечно, важно, чтобы в AH
был ноль, но мы точно знаем, что он и так уже там, поэтому тратить целый байт на повторное обнуление мы не будем.
Продолжение доступно только участникам
Вариант 1. Присоединись к сообществу «Xakep.ru», чтобы читать все материалы на сайте
Членство в сообществе в течение указанного срока откроет тебе доступ ко ВСЕМ материалам «Хакера», позволит скачивать выпуски в PDF, отключит рекламу на сайте и увеличит личную накопительную скидку! Подробнее
Вариант 2. Открой один материал
Заинтересовала статья, но нет возможности стать членом клуба «Xakep.ru»? Тогда этот вариант для тебя! Обрати внимание: этот способ подходит только для статей, опубликованных более двух месяцев назад.
Я уже участник «Xakep.ru»