Info Guide
#13
01 апреля 2021 |
|
GFX - Подготовка графических ресурсов при создании игр на ZX Spectrum
Подготовка ресурсов для игр Alone Coder Представьте,что вы написали почти гото─ вую игру, и тут выясняется, что в ней не хватает одной анимации персонажа. При традиционном (для Спектрума 90-х годов) методе разработки вам придётся от─ дельно сконвертировать фазы этой анимации, а потом приклеить их к существующим - воз─ можно, нарушив нумерацию спрайтов, то есть всё придётся заново тестировать. Представьте,что игра уже совсем готова, но в процессе тестирования в некоторых ка─ ртах обнаружены косяки. При традиционном способе вам придётся сконвертировать эти карты и заново перепаковать диск с игрой, из-за чего, возможно, поедут расположения файлов - и опять полное тестирование. Или другая типичная ситуация - спрайты рисуете НЕ ВЫ, карты рисуете НЕ ВЫ, рисуют это отдельные художники и левелдизайнеры, и они хотят увидеть результат своей работы в рабочей версии игры без вашей помощи. Как быть? Все эти проблемы решает автоматическая сборка. Автоматическая сборка Сделаем оговорку, что некоторые авторы спектрумовских игр отлаживают игры в снап─ шотах, а при сборке финальной версии (если до неё доходит - ведь психологически игра уже готова,и можно на покой) им приходится заново отлаживать игру уже с загрузчиком. Не надо так. Дальше в этой статье мы рас─ сматриваем с самого начала релизную сборку игры. А отладочные функции? Их можно вклю─ чать и выключать условной компиляцией. "Релизная сборка" означает,что игра ле─ гко может быть выпущена в любой момент, а если не выпущена одним автором, то легко может быть поднята из архивов другим (сра─ вните с "мёртвыми" исходниками на сайте opensourcezx, которые уже никто не знает, как собрать). Кроме того, можно легко и непринуждённо делать багфиксы, версии на всех языках и для всех форматов (tap, trd, SD-карта...),хоть даже все одновременно по одной кнопке. Сборка - это последовательность дейст─ вий. И действия эти надо делать не руками, а командами в батнике.Какие это могут быть команды? - компиляция ассемблерного кода со вхо─ дящими инклюдами (например, ассемблером SjASMPlus ).В игре не обязательно один не─ зависимый кусок кода - бывает интро,аутро, меню... - упаковка кодового блока (например,ути─ литой mhmt ) - конверсия картинки во внутренний фор─ мат (например,под экран ATM-Turbo утилитой convega - см. nedoos/src/games/barbaria/ ) - вытаскивание спрайтов во внутренний формат (например, утилитой nedores ) - конверсия карт, скриптов и т.п. - создание образа диска/ленты/SD-карты, копирование файлов туда (например, утили─ тами trdtool, nedotrd, dmimg, bin2tap ) Как привязать спрайты к коду Есть две типичные ситуации: а) блок спрайтов содержит спрайты одного размера,с доступом по номеру(таких блоков может быть много); б) блок спрайтов содержит спрайты разного размера с доступом по имени. Несмотря на то,что первый вариант иног─ да выигрывает по размеру, я рекомендую ис─ пользовать второй.Дело в том,что в номерах спрайтов очень легко запутаться, особенно если вы (или продолжатель вашего проекта) будете возвращаться к игре через долгое время. Имея доступ по имени, легко описать структуры с анимацией. Идеально, конечно, было бы анимировать спрайты в программах, которые для этого предназначены (например, Aseprite или Pixelorama ),но утилиты импо─ рта из них ещё не написаны. А старые спек─ трумовские редакторы спрайтов не поддержи─ вают слои, просвет анимации и цвет на точ─ ку. Поэтому для перспективных игр пока что приходится вытаскивать спрайты из bmp. К счастью, для вытаскивания из bmp есть обкатанная утилита nedores (в составе NedoOS ),которую несложно расширять новыми форматами. Что делает nedores? Она открывает файл bmp (17-цветный - для прозрачности при цвете на точку) из первого параметра, скрипт-описатель спрай─ тов из второго параметра и имя выходного ассемблерного файла из третьего параметра. Скрипт-описатель выглядит, например, так: ;x,y,wid,hgt,defaultcolor (0..15 that will ;be used as ink in empty chr$) ;6912: color 0 in bmp is for mask ;16c: color 16 in bmp is for mask ;formats: ;B: colour tiles: wid, hgt, data ;s: b/w sprites:wid8,hgt,(antimsk,antipix) ;w: b/w sprites: antipixelsw, antimaskw... ;W: b/w image by columns ;T: colour tilepic 28xN (size 0xN00 bytes) ;x: 16c spr: wid/2,hgt,(column:and,or..), ;(0x4000-((hgt-1)*40))...,prsprqwid ;L: 16c 16x16 tiles (N of tiles in ;"defaultcolor"): ;N of tile for each square ;i: 16c image ;P: DDp palette human0=x,0,0,16,16 human0step=x,16,0,16,16 human1=x,32,0,16,16 human1step=x,48,0,16,16 ... bulletright=x,16,16,8,8 bulletleft=x,24,16,8,8 Здесь для каждого вырезаемого спрайта указано имя, формат ("x" - формат спрайта для sprexamp/prspr.asm ), расположение на картинке и размер. prspr по умолчанию под─ держивает любую чётную ширину и высоты 8, 16, 24, 32, но при желании этот список нетрудно изменить или дополнить. В результате выполнения nedores возни─ кает такой ассемблерный файл: human0=$+4 ;ld iy,human0:call prspr db 0x08 ;ширина (в двойных пикселях) db 0x10 ;высота db 0xff,0x00 ;маска,графика db 0xff,0x00 ;... db 0xff,0x00 db 0xff,0x00 db 0xff,0x00 db 0xff,0x00 db 0x47,0x00 db 0x47,0x00 db 0xff,0x00 db 0xff,0x00 db 0xff,0x00 db 0xff,0x00 db 0xff,0x00 db 0xff,0x00 db 0xff,0x00 db 0xff,0x00 dw 0x3da8 ;смещ-е до след.столбца экрана db 0xff,0x00 ;маска,графика db 0xff,0x00 ;... db 0xff,0x00 db 0xff,0x00 db 0x47,0x00 db 0x00,0x08 db 0x00,0x09 db 0x00,0x09 db 0x00,0x08 db 0x47,0x00 db 0xff,0x00 db 0xff,0x00 db 0xff,0x00 db 0xff,0x00 db 0xff,0x00 db 0xff,0x00 dw 0x3da8 ;смещ-е до след.столбца экрана ... db 0xff,0x00 ;маска,графика db 0xff,0x00 ;... db 0xff,0x00 db 0xff,0x00 db 0xff,0x00 db 0xff,0x00 db 0xb8,0x00 db 0xb8,0x00 db 0xff,0x00 db 0xff,0x00 db 0xff,0x00 db 0xff,0x00 db 0xff,0x00 db 0xff,0x00 db 0xff,0x00 db 0xff,0x00 dw 0xffff ;невозможное смещение =признак ;конца спрайта dw prsprqwid ;туда будем выходить human0step=$+4 ;ld iy,этаметка:call prspr db 0x08 ;ширина (в двойных пикселях) db 0x10 ;высота db 0xff,0x00 ;маска,графика db 0xff,0x00 ;... db 0xff,0x00 db 0xff,0x00 db 0xff,0x00 db 0xff,0x00 db 0xff,0x00 db 0x47,0x00 db 0x47,0x00 db 0xff,0x00 db 0xff,0x00 db 0xff,0x00 db 0xff,0x00 db 0xff,0x00 db 0xff,0x00 db 0xff,0x00 dw 0x3da8 ;смещ-е до след.столбца экрана ... Для режима "цвет на точку" можно также импортировать картинку по столбцам ( "i" - применимо и для шрифтов) и набор тайлов 16x16 с описанием, какой номер где стоит на картинке (примеры см. в src/games/br/ images/W1LAND.dat и в src/games/sprexamp/ tiles.dat ). Также nedores умеет импортировать чёр─ но-белые спрайты "s" и "w" и цветные тайлы "T" для режима 6912 (используются в nedolang/_sdk/sprite.i и в Dizzy SE ). Мо─ жно импортировать и отдельные цветные тай─ лы для этого режима ( "B" ).Можно импорти─ ровать ч/б картинку по столбцам ( "W" ). Поскольку на выходе nedores получается исходник,его можно компилировать под любой адрес и при этом иметь доступ к спрайтам по имени. Вот как описывается типичная анимация: heroanim_runright dw HERORUNRIGHT0 ;спрайт фазы db 4 ;задержка этой фазы dw HERORUNRIGHT1 ;спрайт след.фазы db 4 ;задержка этой фазы dw HERORUNRIGHT2 ;спрайт след.фазы db 4 ;задержка этой фазы dw heroanim_runright ;адрес след. ;анимации ;(после окончания текущей) Но если спрайты не помещаются в страни─ цу, то задача усложняется... В примере sprexamp вместо адресов спрайтов всё-таки используются номера (а точнее,адреса адре─ сов),которые пришлось там же (sprdata.asm) описать как константы. Но никто не застав─ ляет делать именно так.Можно написать ути─ литу автоматической генерации номеров спрайтов из их адресов, или можно при ком─ пиляции игры инклюдить страницы спрайтов и самому следить за номерами страниц. Разумеется,номера страниц спрайтов дол─ жны быть логическими, а не теми, которые пишутся в порт, ведь компьютеры,на которых будет запускаться ваша игра, могут быть разными, а под NedoOS игра вообще может быть загружена в случайные страницы. Работа с картами Некоторые игры требуют собственных ре─ дакторов карт (например,если карта строит─ ся из стен, как в Wolfenstein 2004, или из объектов, как в Ball Quest и Dizzy ). Но для большинства игр достаточно прямоуголь─ ной сетки и редактора MapWin. Этот редак─ тор позволяет написать собственный скрипт сохранения в нужном формате, причём этот скрипт может выгрузить более одного файла (например, координаты врагов отдельно). MapWin также поддерживает многослойные ка─ рты (расположение предметов,входов,выходов логично делать на отдельном слое) и авто─ матическое разрезание картинок на тайлы. Примеры работы с MapWin можно увидеть в Unreal Project и sprexamp в NedoOS. Иногда левелдизайнеру удобнее рисовать карту в самой игре (так было в Space Monsters meet THE HARDY ). В этом случае лучше отказаться от внешнего редактора, чтобы не делать конверторы в обе стороны. А дальше есть два подхода: 1. Если сама игра умеет сохранять карты, то нужно только написать в батнике сборки чтение готового файла из образа в директо─ рию с исходниками. 2. Если игра не умеет сохранять, то надо дать инструкцию левелдизайнеру, как делать снапшот, а в отдельном батнике прописать вызов утилиты, которая будет доставать ка─ рту из снапшота. Хорошо, если для этого достаточно обкусить файл (например, утили─ той nedopad ).Можно прописать этот вызов и в батнике сборки, но тогда снапшот станет первоисточником карты, что негигиенично. Работа с музыкой и звуками Особенность музыки и звуков та же,что у карт - редакторы ( Vortex Tracker , AY FX Editor ) выгружают их уже в виде,пригодном для использования в коде. Наша задача в батнике - просто скомпилировать плейер с этими файлами или учесть в загрузчике, чтобы они грузились отдельно. Музыканту достаточно знать, под какими именами их надо сохранять. Если же плейер нестандартный,а его ком─ пилятор не работает в командной строке, то придётся пересобирать музыку в бинарники вручную каждый раз, когда музыка измени─ лась. Это неудобно, и надеюсь, что авторы компиляторов в будущем учтут эту проблему и решат её, например, так: - По умолчанию есть компилятор, который просто запускается в командной строке с именем файла. - Если компилятор требует ручных настро─ ек,то можно сделать его интерфейс отдельно от самого компилятора и передавать параме─ тры в командной строке с возможностью ко─ пирования к батник. - Если компилятор генерирует ассемблер─ ный исходник,то части этого исходника дол─ жны инклюдиться,чтобы пользователь мог сам подправить адрес, вход, выход и положение модуля относительно плейера. Работа со скриптами Обычно удобнее всего редактировать скрипты в текстовом виде. Чтобы не писать для них отдельный парсер,язык скриптов лу─ чше взять готовый - ассемблер или Си. Они позволяют с помощью макросов определить нужные слова-команды, а если особых команд нет, то можно писать просто через DB и DW. Можно писать скрипты и на Nedolang, но по─ скольку там нет макросов, то скриптование ограничено написанием однотипных структур данных. Другой вариант - если сама игра будет искать управляющие последовательности в тексте. Такая игра будет работать медлен─ нее. Если игра в основном строится на диа─ логах, то это терпимо. Нетерпимо, если под эти диалоги в конце концов не хватит места в памяти. Тогда придётся разрабатывать от─ дельную утилиту сжатия, а для этого отка─ заться от записи вида: text1 db "text 1",0 text2 db "text 2",0 и перейти на таблицу адресов сообщений, которую эта утилита тоже будет генериро─ вать. Хорошо, если она сгенерирует её в виде ассемблерного текста: text1=_+0 text2=_+5 Тогда не нужно место под таблицу, можно инклюдить этот ассемблерный текст и ссы─ латься прямо на метки text1 и text2. Понятно,что для этого структуры со ссы─ лками не должны паковаться в том же прохо─ де, что и тексты. Тема скриптов очень обширна, вариантов множество, некоторые мы уже обсуждали в прошлых номерах Info Guide. Но непреодоли─ мых проблем для автоматизации нет. * * * Обратите внимание, что автоматическая сборка не обязательно подразумевает Win─ dows. Её можно применять и на Спектруме, например, в NedoOS. Даже в ALASM я долгое время использовал автоматическую сборку из двух шагов (компиляция и упаковка), это сильно облегчало жизнь при написании сис─ темных программ. Там можно было ещё делать произвольные вызовы во время компиляции (директива RUN ) - например,для чтения си─ стемного времени. Но более сложные после─ довательности действий ALASM не поддержи─ вает. Я писал на ALASM 18 лет подряд и до сих пор иногда к нему возвращаюсь. Но всё реже и реже. Когда вы переходите на автоматическую сборку,сначала она кажется сложной или ме─ дленной (ведь результат не возникает сразу в памяти!). Но стоит вам как следует наст─ роить среду разработки и батники, и воз─ врат к ручной сборке кажется бессмысленным и чреватым ошибками. Особенно вы её оцени─ те, если в проекте уже несколько человек или планируется долговременная поддержка.
Другие статьи номера:
Похожие статьи:
В этот день... 21 ноября