Info Guide #08
30 ноября 2005
  Игры  

Gamedev - Советы при написании аркадной игры.

<b>Gamedev</b> - Советы при написании аркадной игры.
   Написание аркадной игры
   После сборки 16-цветного девайса на пе─
нтагоне (см.статью) я решил закрепить этот 
успех написанием игрушки под 16 цветов.Бы─ 
ла выбрана идея игры Pang. Сначала я скон─ 
струировал  шарики (в фотошопе с использо─ 
ванием преобразования декартовых координат 
в полярные) и написал  выводилку  спрайтов 
(чтобы  посмотреть, как эти шарики прыгают 
на  фоне  картинки). Выводилка  спрайтов и 
стиралка спрайтов попеременно вызываются в 
цикле LOO (так в программе и сейчас). Пока 
обновляется 2-й экран,видно 1-й,и наоборот 
(так и сейчас). 
   Спрайты конвертировались из 16-цветного
.bmp (палитру для конверсии можете нарисо─
вать сами, это очень просто: сначала неяр─
кие, потом яркие, в стандартом порядке,0-й
цвет  будет прозрачный) прилагаемым исход─
ником bmpTOspr.H. Исходник  bmpBKspr.H де─
лает то же самое, но переворачивает спрайт
лицом  влево, если  он был лицом вправо (и
наоборот).
   Потом  я попросил  Shiru Otaku вытащить
цветные  спрайты персонажа и прочих объек─
тов этой игры с первой попавшейся пристав─
ки. Shiru Otaku работает очень быстро, по─
тому  нужные спрайты были добыты за 3 дня.
Они  (в SNES версии)  нарисованы под 32768
цветов (16 цветов на спрайт, 256 цветов на
экран). Перевести все эти цвета в 15 стан─
дартных было очень просто - достаточно бы─
ло  разложить все спрайты на одну картинку
(получилось  около 60 разных цветов) и от─
редактировать цвета в палитре.При этом да─
же  сохранились практически все цветопере─
ходы.Благодаря тому,что в SNES-версии раз─
решение  256x224, не  пришлось масштабиро─
вать спрайты.

   Параллельно  я добавил в программу (ко─
торая,как вы помните,умела только выводить
спрайты) следующие вещи:
 

  1. Интеллект, который работает на преры─
вании (см.статью про игровой цикл в IG#6).
Этот  интеллект оперирует 11-байтными опи─
сателями  юнитов (тип персонажа, его фаза,
координаты,скорости,время и энергия). Эне─
ргия в Pang не нужна,это поле зарезервиро─
вано для игр-"стрелялок". Оно двухбайтное,
потому что  в Wolf2004  еле хватало одного
байта, хотя  в Wolf2004 нет боссов с кучей
энергии (способ  убивания  Гитлера основан
не  на энергии, а на хитрости). К слову, в
Wolf2004  ещё и не было скоростей движения 
спрайтов. Взамен организовывался временный
(!) буфер направлений движения  для персо─
нажей, близких к игроку. Так пришлось пос─
тупить  из-за  того, что  монстр/объект  в
Wolf2004 с древних времён описывался 8 ба─ 
йтами,и разбайтовка этих байт торчала сли─
шком  во многих местах программы (не через
индексные  регистры) - переделать  было бы
очень трудно. В Wolf2004 нужно было разде─
лить  живых  и неживых персонажей в разные
списки  в разных  форматах  (живым  больше
байт, неживым меньше). Но это не было сде─
лано.Увеличить универсальный описатель с 8
байт до  9 и выше было нельзя - не хватало
памяти, например, на  уровне L. Впрочем, в
Wolf2004 есть несколько свободных килобайт 
в верхней памяти,там предполагалось разме─
стить работу с сетью (LAN).
 

  2. Пересчитывалка координат персонажей в
координаты на экране,передаваемые в список
SPRS (которым  пользуется процедура вывода 
спрайтов). Заодно тип персонажа и фаза пе─
ресчитываются  в  адрес спрайта. И вообще,
переброска перед выводом требуется для на─
дёжности - ведь если из цепочки был удалён
один  персонаж (а удаляется он по прерыва─
нию,т.к.интеллект висит на прерывании!),то
выводилка может случайно перескочить через
конец списка или может взять половину дан─
ных от одного  персонажа (и тут случайно -
БАЦ - прерывание!), а вторую половину - от
другого.Так что если перекидывалка узнаёт,
что  во время её выполнения произошло пре─
рывание, она начинает перекидывание снача─
ла. В Wolf2004 персонажи не удалялись (ка─
жущееся  "удаление" - это просто занесение
в  Y-координату  специального  числа) и не
добавлялись,поэтому не требовалось копиро─
вание списка персонажей перед циклом выво─
 да.
   Чтобы совсем избавиться от глюков,позже
я организовал: 2.I. Проверку на случай пе─ 
реполнения буфера под спрайтами. 2.II. Вы─ 
ход из цикла искусственного интеллекта по─ 
сле выполнения операций удаления каких-ли─ 
бо персонажей (можно было поступить иначе: 
сдвигать текущий указатель юнита, если был 
удалён кусок списка,лежавший в памяти ниже 
этого юнита). 
 

  3. Списки фаз для пересчёта фаз персона─
жей в адреса спрайтов.
 

  4. Для  каждого  персонажа  адрес списка
фаз (п.3) и адрес процедуры обработки пер─
 сонажа (для цикла интеллекта).
   Сначала спрайты не имели заголовка,и их
размеры лежали отдельно.Заголовок я сделал 
потом. Длину спрайта в байтах я внёс в за─ 
головок  в самый  последний момент, раньше 
эта длина вычислялась. Поэтому в исходнике 
такая оригинальная загрузка спрайтов - че─ 
рез макрос iNCBIN. Этот макрос подставляет 
в заголовок  спрайта  то самое поле длины. 
Макрос  выглядит так запутанно потому, что 
для работы он должен узнать текущее смеще─ 
ние компиляции (ведь спрайты грузятся вну─ 
три блика DISP..ENT !). 

   Фоновые  экраны  у  меня  первоначально
грузились просто из bmp,лежащего на диске─
те. Но это неудобно и некрасиво. Поэтому я
организовал упаковку. Если,например,заста─
вку  к Pang  паковать  в виде 4bit bmp, то
получается rar размером 2790. А если пако─
вать разложенную по столбцам,то получается
rar  размером  2254. XOR между строк и XOR
между столбцов не помогает.
   Распаковка  заставок (DEPKS16) происхо─
 дит так:
  1. включаем  1-й экран (мог быть включен
 2-й). 
  2. очищаем 2-й экран;включаем 2-й экран.
(Вариант: 2.очищаем #5800..#5aff; включаем 
 6912 режим.) 
  3. bmp, упакованный rar'ом (без заголов─
ка),кладётся в хвост страницы #14. (Удобно 
перекидывать  из  другой  страницы через 2 
 LDIR'а, используя область #a000...#bfff.) 
  4. вызывается  smallunr.H  (с параметром
RARS=#6000) - распаковка rar на адрес чуть 
ниже #a000 (например, #9f00). Назовем этот 
 адрес "addr". 
   Сейчас данные в addr..addr+#5fff (почти
 до конца памяти), включена #14 страница. 
  5. разворачиваем  экран #4000 (начиная с
 addr+192, после столбца пропускаем 3*192). 
  6. разворачиваем  экран #6000 (начиная с
 addr+(3*192)). 
  7. убиваем  каждый  2-й  столбец в блоке
данных (192 байта копируем, 192 пропускаем 
 и т.д.). 
   Сейчас данные в addr..addr+#2fff (почти
 до #d000). 
  8. разворачиваем  экран #e000 (начиная с
 addr+192, после столбца пропускаем 192). 
  9. убиваем  каждый  2-й  столбец в блоке
 данных. 
   Сейчас данные в addr..addr+#17ff (почти
 до #b800). 
  10. разворачиваем экран #c000 (берём ба─
 йты с addr, подряд). 
  11. включаем 1-й экран (или включаем 16-
цветный режим, если выключили). 
   Как  видите, используется  всего 2 дей─
ствия-процедуры  ("разворачивать"  и "уби─
вать") и  не  используются  лишние области
памяти (кроме  остатка  одной  из экранных
страниц - страницы #14 )! (На АТМ страницы
другие.) Память #a000..#bfff - буфер изоб─
ражения  под спрайтами, и его вполне можно
портить, пока спрайтовый движок не вызыва─
ется. А вызывается он  только внутри цикла
LOO. 
   Дальше  было просто добавление програм─
мок  и подпрограммок искусственного интел─
лекта. Эти программки  довольно однообраз─
ны. Во всех  используются одни и те же ре─
гистры: IX (адрес описателя персонажа), BC
(Y), DE (X). Сделана сначала одна процеду─
рка проверки коллизий,а потом ещё две.Одна
проверяет  коллизию героя с врагами (вызы─
вается  из обработчиков героя и перебирает
врагов, хотя можно было бы вызывать из об─
работчиков врагов и ничего не перебирать -
герой-то  один). Другая проверяет коллизию
гарпуна с врагами (аналогичное замечание).
Третья - коллизию героя с призом.
   Были  между  делом нашлёпаны процедурки
вывода счёта и времени, таблички уровней и
прочая мелочь.
   В конце концов из запасников были выта─
щены маленькие музончики (которые  я писал
в 2002-2004 гг.) и  вставлены  в игру. Был
взят модуль звуковых эффектов  из  старого
доброго Wolf2004, в звуках немного измене─
ны параметры.Этот модуль не универсальный,
он  умеет  играть  только  небольшой класс
звуков (например, в процессе  проигрывания
эффекта  не могут меняться периоды тональ─
ника и шума).
   Сборка игры во время её написания прои─
зводилась много раз (как минимум перед ка─
ждым  тестированием на реальном пентагоне)
и проблем не вызывала, т.к.это автосборка.
Основной блок плюс спрайты пакуется в бей─
сик-файл. Файлы с музыкой и картинками ле─
жат  отдельно и подгружаются (в странички)
через  #3d13 после старта игры. Программу,
оформленную таким образом, можно пересоби─
рать хоть по 100 раз на дню. Меня удивляют
некоторые программисты, которые при каждой
сборке  своих  программ  вручную запускают
пакер и так же вручную приклеивают загруз─
чик (вручную вводя размеры файлов и пр.).
   Программа  писалась  под  Unreal Speccy
v0.32b8  и между делом проверялась на реа─ 
льном  пентагоне. SMT оперативно организо─
вал  поддержку  16-цветного  устройства  в
эмуляторе,благодаря чему перетаскивать иг─
ру на пентагон для проверки приходилось не
так  уж часто. От момента запроса спрайтов
до релиза игры, т.е. показа её заинтересо─
ванным лицам (в двух сборках:для Пентагона
и АТМ !) прошло  17 дней. Для меня это ре─
корд. Лестницы и блоки  я делать не стал -
игра и сейчас имеет хорошую playability,да
и проект изначально задумывался как недол─
гий.

        Об ускорении этого движка.

   Программа создавалась как кроссплатфор─
менная - легко переделываемая, кроме того,
обучающая  -  легко  понимаемая  (обратите
внимание  на количество комментариев в ис─
ходниках). Поэтому хитрости не были приме─
нены.
 

  1. На  АТМ можно поместить страницу гра─
фики  в область ПЗУ  и не LDIR'ить спрайты
перед  выводом. Того  же можно добиться на
пентагоне, если  положить самые популярные
спрайты  (т.е. шарики  и верёвку - итого 4
спрайта) в нижнюю память  и вставить небо─
льшую проверку перед LDIR'ом. Попробуйте в
исходнике. Выигрыш  должен  быть небольшой
- 21 t/байт  (сейчас  ў130 t/байт, включая
RESPR ). Причём  этот выигрыш считается от 
процессорного  времени, оставшегося  после
вычитания  времени на музыку (5% для 70000
t),интеллект (10% по оценке для 70000 t) и
вывод цифр (5%?). Т.е. общий выигрыш можно
оценить  в (21 t/130 t)*(100%-10%-5%-5%) <
< 13% времени. На пентагоне в нетурбо выи─ 
грыш  меньше - где-то  11%  (т.к.  45000 t
вместо 70000 t,в силу чего музыка и интел─
лект забирают порядка 30% ).
 

  2. При использовании большого объёма па─
мяти  можно хранить картинки распакованны─
ми,а шрифт - в виде спрайтов букв под раз─
ные раскраски. Но и сейчас можно не распа─
ковывать  одну и ту же картинку перед каж─
дым входом в один и тот же уровень, а про─
сто  стереть  с неё спрайты (с обоих экра─
нов). Попробуйте в исходнике.
 

  3. При наличии копии заднего плана можно
не сохранять фон под спрайтами,а восстана─
вливать  его прямо из копии заднего плана.
На  пентагоне неактуально (рабочий экран и
копия  заднего  плана не помещаются в одно
адресное пространство),сработает только на
АТМ. Выигрыш  не больше 16 t/байт (сколько 
точно - не ясно, т.к.должен быть полностью
переписан  RESPR ). И  две  проблемы: 3.I.
вывод цифр замедляется в полтора раза (ес─
ли считать,что они уже развёрнуты по реко─
мендации 2 ); 3.II. при  написании  игр со
скроллингом скроллинг замедляется в полто─
ра раза,а он и так должен быть ужасно мед─
ленный (вывод двух экранов,т.е. 48k!). Ко─
нечно, для  некоторых  игр вообще не нужно
запоминать  задний  план и восстанавливать
его под спрайтами - можно просто перестра─
ивать  весь  задний план (на одном экране,
т.е. 24k) в начале  каждого  цикла  вывода
спрайтов.

Alone Coder 



Другие статьи номера:

Inferno - Авторы журнала.

Inferno - Вступление от редактора.

Inferno - Ошибки в предыдущих номерах.

Inferno - Об оболочке.

Железо - CD-ROM - устройство и хитрости подключения.

For Coderz - CD video на ZX. Как написать плеер видео с компакт-диска.

Sofтинка - Техническое руководство по дисковой системе DISCiPLE/+D.

For Coderz - Маленькие программерские хитрости.

Математика - История решения теоремы Ферма.

Gameland - Игра Шестнашки.

Sofтинка - Описания и история изменений программы для работы с жестким диском HDDoctor v0.9.

Секреты - Секретные кнопки в разных приложениях: Wolfenstein'2004, IG#5, ACEdit, DNA OS, Wild Disk Copier.

Sofтинка - Улучшения конвертора графики в Gigascreen.

Звук - Ламповые усилители. Стерео лампочник 2х5 Вт из старых телевизоров.

Железо - Обзор кассетных проигрывателей.

Inferno - Письма в редакцию.

Gamedev - История создания игры Pang.

Gamedev - Советы при написании аркадной игры.

Реклама - Реклама от Романа Чунина.

Реклама - Реклама от Алексея Жабина.

Реклама - Реклама от В. Богдановича.

Интервью - Интервью с Николаем Родионовым, автором известных книг для ZX Spectrum

For Coderz - Вычисление тригонометрических и алгебраических функций в языках высокого уровня.

DIY - схема 16-цветного видео-режим v1.1 для пентагона.

Железо - Описание микросхемы К555ТЛ2.

For Coderz - Программирование устройства генерации звука Turbo Sound.

Sofтинка - 384x304 viewer. программа позволяющая просматривать цветные картинки, по размерам превышающие экран.

Sofтинка - Эмулятор ZX Spectrum на ZX Spectrum.


Темы: Игры, Программное обеспечение, Пресса, Аппаратное обеспечение, Сеть, Демосцена, Люди, Программирование

Похожие статьи:
Игры - Как обесмертить игру Carries Command. POKE's для игры King Bounty.
Вступление - От авторов.
Coding - Драйвер RAM DISK'а для ZX-Spectrum'128.
Учимся кодить вещи - изящнaя oчисткa экpaнa.
Coding - Как перехватить Magic и Reset на компьютере ZS256.

В этот день...   21 ноября