Back-инжиниринг Caesar III (часть 2, Рисование города)

Надеюсь, предыдущий пост Back-инжиниринг Caesar III, где был описан алгоритм получения текстур из ресурсов оригинальной игры, был благосклонно встречен хабражителями. В этой статье я опишу формат карт, алгоритм выбора и порядок тайлов для отрисовки, формирование итоговой текстуры.548fe94ac86b7849c40361db95020a48.jpg

Если знаете, что такое тайл (tile), тогда следующий раздел можно пропустить.ТайлыТайл это картинка фиксированного размера, сформированное так, чтобы при рисовании рядом с другими тайлами получалось сплошное изображение без «швов». Вот пример текстур травы из игры Caesar III©

e8f45088f7bb8264022f0802336b5d9d.pngc99835a7a20b3f0872735f134d8a41d4.pngf1c94f9131045f295f86d72a04878b6d.png19c06ac2ad3ae9ff69ecc30baa3094b1.png282ddc4010aa32acdf6975db0c8a9d8c.png8981ed98141138e25dff8f61cc334adb.png39e3142b195ee7697b31ef8d9a0ca03c.png1ddce8acb76df6b15dda8734264ad1c0.png

Если составить их рядом в определенном порядке и добавить немного текстур с деревьями, то получится некоторая область земли.А если внести в эту живописную картину еще один вид тайла, например, с изображением дороги, то можно уже составить примитивную карту.

0be7463187f6e117ba00ea8a75071324.png5b7c92d96959fcaadf311b2e2180a683.pngВы, наверно заметили, что представленные изображения не квадратные, а ромбовидные. Сделано это для того, чтобы придать изображению ощущение объема (глубины). Такой тайл выглядит повернутым одним углом к зрителю и как бы уходящим вглубь, двухмерная картинка приобрела третье измерение. Для создания эффекта объема ширина должны быть меньше длины примерно в два раза. База тайла в игре Caesar III составляет 58×30 пикселей, это минимальный размер тайла, которым оперирует движок игры. На первых этапах разработки ремейка получился один неприятный эффект, текстуры в игре созданы без учета прозрачности и вывод их на экран без дополнительной обработки приводил к следующему результату.1f4cb2f94ffecfc0020eac3920a8f44f.pngВыход из этой ситуации следующий: либо использовать маску, например цвет крайнего левого символа принимается как прозрачный, либо текстуры дополнять альфаканалом. В оригинальной игре использовался первый вариант, в ремейке используется второй: текстуры подготавливаются на этапе загрузки ресурсов.

КартаКарта — это массив, определяющий положение тайлов на слое и их параметры. В самом простом случае карта представляет собой матрицу MxN, где каждый ее элемент содержит идентификатор (номер, число) из условной «палитры тайлов». Тайлы не обязательно имеют последовательный порядковый номер, номера тайлов разбиты на несколько интервалов и именованных пространств. Так например тайлы земли, деревьев, воды, разломов и травы имеют индексы от land1a_00001 до land1a_00303. В игре Caesar III допускается использование квадратных карт размеров от 30×30 до 160×160 тайлов. Тайл располагается на карте так, что его верхняя границы является «севером»944b0659be7c1fab7fa7e6cbc97cf0df.jpg.Для того, чтобы нарисовать тайлы на экране, нужно учитывать расстояние до него, если просто нарисовать тайлы в порядке их размещения на карте, то получится абракадабра, так как часть тайлов была нарисована не в свое время.32b59e2147d77ccf20016b142d02c4ce.png

В какой последовательности нужно рисовать тайлы показывает следующее изображение.bd78a9a62a648a5a6e05897025db0a48.jpg1. В первой фигуре показан порядок отрисовки тайлов на 2D карте, для создания эффекта глубины2. Во второй фигуре показан порядок отрисовки тайлов на 2.5D карте, учитывая, что чем выше расположен тайл, тем раньше он должен быть отрисован.

de74dbc49c4eada6dfc703e7c95d7075.pngЭто изображение сформировано из следующих тайлов, отрисованных в правильном порядке.

694cc12cad6be63938768f7e79e92046.png

В общем случае код формирования индексов тайлов для отрисовки будет следующим

Посмотреть //Формируем верхнюю часть «ромба» отрисовки tilemap map; //карта поверхности tilearray tiles; //порядок отрисовки for (j=0; y < map_size; j++ ) { for( t=0; t <= j; t++ ) { tiles.append( map[ t , map_size - 1 - ( j - t ) ]; } }

//Формируем нижнюю часть «ромба» отрисовки for (i=1; i < map_size; i++ ) { for( int t=0; t < map_size-i; t++ ) { tiles.append( map[ i + t, t ] ); } } Рисование городаДополнительные условия, которые возникают при отрисовке города.1. На карте расположены не только статические тайлы земли, травы, зданий, а также присутствуют подвижные объекты (люди, животные, анимация)2. Есть объекты, через которые можно пройти (арка, ворота, амбар)3. Дополнительная анимация тайлов и объектов4. Неквадратные объекты

Эти условия усложняют процесс отрисовки и порождают дополнительные правила отрисовки.1. Перемещение персонажей по изометрической карте происходит не просто так. Карта повернута «вглубь» и абсолютный ее размер по вертикали не совпадает с размером по горизонтали. Поэтому и «вверх» любой ходячий предмет должен двигаться соответствующим образом, в простейшем случае на два шага в сторону приходится один шаг вглубь.2. Подвижный объект может находиться в разных частях тайла и рисуется он после отображения основного изображения тайла, что может вызвать артефакты отображения, например такие: колесница едет поверх ворот. Это обходится рисованием дополнительных спрайтов, которые будут показаны после отрисовки подвижных объектов.cc76d441fc7ba1e5adee5222446c3034.png + 1d09a934b57a38342cc77b123fe3b5ea.png = 58b5f38729c5982b2548c0a715d5483c.png3. Анимация может выходить за размеры основного изображения, здесь следует учитывать такую особенность, что она (анимация) может уходить вверх и вправо, но не вниз и влево, иначе она будет перекрыта следующими тайлами.4. В большинстве своем в игре используются квадратные объекты, но есть и протяженные, для упрощения алгоритма отрисовки, их бьют на более мелкие (квадратные) части, например ипподром.2e066efcdd9d5db9422ec5ed6ae5d006.png = 61a6c466740f1f46540c6172a980514a.png + ec7bb7244b3d743a8990789d894e039c.png + 93c02e83a0684d8fe134f13d1fbd3f2b.png

Как рисовать1. За первый проход рисуются «плоские» тайлы и подвижные объекты на них2. За второй проход рисуются тайлы, изображения которых может выходить за базу тайла3. Рисуется дополнительная анимация для тайлов, которые имеют такой флагПредваряя возможные вопросы. Этот алгоритм был восстановлен из оригинальной игры, настолько, насколько я смог его понять, возможно он будет изменен в более поздних версиях. Советы по организации цикла отрисовки приветствуются

Формат карты игры Caesar IIIНепосредственно к объектам, которые будут отображены в городе, в файле *.map относятся первые пять блоков данных. Читаем с начала файла, вычитываем данные друг за другом без пропусков.

short tile_id[26244] — содержит идентификаторы элементов, каждый идентификатор соотносится со своей текстурой. Например группа идентификаторов 246–548, соответствует текстурам land1a_00001-land1a_00303, это текстуры земли, деревьев и др., которые были описаны выше.byte edge_data[26244] — массив содержит информацию о размерах объекта, для которого выбрана текстура в массиве tile_idshort terrain_info[26244] — массив содержит характериски поверхности для конкретного тайла, земля, вода, дорога, стена и др. (полная информация по этим флагам)byte minimap_info[26244] — базовая информация для построения миникарты, также участвует в некоторых вычислениях в ходе игры, выступая своего рода массивом «случайных чисел».byte height_info[26244] — этот массив описывает высоту тайла над поверхностью, 0 — для земли, 1 — 15 пикселей, 2 — 30 пикселей и и тд.

Практическое применениеБолее подробную информацию об игре Caesar III© и ходе разработки ремейка вы можете найти в нашей вики на bitbucket.org.Отдельное спасибо Bianca van Schaik за помощь в написании статьи и предоставленные материалы.

И напоследок небольшой тестовый скриншот, этрусские копьеносцы бесчинствуют в городе фонтанов60980b50a1c7fdcc61d8ef6576475ff6.jpg

© Habrahabr.ru