Как-то мне попалось мини-интервью Джона Ромеро, его там спросили под каким углом стреляет Дейв. Ответ был — 45 градусов. Я тогда удивился, почему вообще возник такой вопрос у народа. Поизучал траектории полета пули в оригинале и тоже удивился: что-то там не похоже на 45 градусов никак:
Пришлось немного повысчитывать, но все получилось, теперь Дейв стреляет:
И вот появилось ощущение той самой игры! Теперь надо или подумать над звуками в игре, или заняться монстрами, разлетающимися кусками от них и т.д.
P.S. Совсем забыл — надо же перезарядку дробовика еще сделать 🙂
Добавил анимацию стрельбы и дыма при выстрелах. 6 видов дымов! Один из спрайтов стрельбы оказался с кривым контуром — слишком толстым. Выглядит он как будто с тенью на стене. Поищем, починим. Теперь надо делать обработку попаданий и расход патронов. Гонять стало сразу куда прикольней!
Добавил движения прицеливания. С джойстиком все ок, а вот на клавиатуре придется делать кнопки сразу стрельбы, а не прицеливания. Потому что клавиатура БК не позволяет обработать нажатие двух клавиш. Точнее, есть один способ (через команду RESET), но во-первых работает он только на реальном железе, а во-вторых так вылавливаются далеко не любые сочетания клавиш. И тем более нельзя будет задавать произвольные клавиши для такого метода опроса. Так что от этой мысли я отказался.
Итак, шкафы Дейв научился открывать и пришло время брать из этих шкафов всякие бонусы. А значит, нужно было заняться анимацией вещей типа цифр с количеством очков, которые вылетают при взятии предметов. Сначала я выяснил, что в оригинале Дейв выводится поверх этих самых «очков». Стало быть, надо накладывать эти спрайты на фон, а уже на них накладывать Дейва. Напомню, что в AZBK есть три экранных слоя, каждый из них обладает независимым скроллингом. Самый нижний слой у меня использован под фон, а также на нем выводится анимация статичных предметов — тех самых алмазов. Анимация выводится на фон, фон двигается, все отлично. Спрайты очков, как выяснилось, тоже привязаны к фону — если Дейв берет предмет и убегает, то цифра с очками уезжает в сторону вместе с фоном. Значит эту анимацию логично вывести на нижний (фоновый) слой и забыть о ней — она сама уедет куда надо, когда фон сдвинется. Но вот только при этом надо сохранять фон, который запортится при выводе спрайтов. Или же выводить заново тайлы обстановки, по которым проедутся спрайты цифр. Последовательность «запомнить фон — вывести спрайт — восстановить фон» тоже не так проста, как кажется. Ведь на этапе «запомнить фон» можно запомнить фон вместе с куском уже выведенного рядом спрайта такой же анимации — ведь очки вылетают и из убитых врагов, которые могут ходить толпами. Поэтому сначала надо восстановить фоны под ВСЕМИ спрайтами анимации, потом запомнить «чистый» фон для каждого спрайта, а потом уже выводить новые спрайты. Ну и при этом всем фон у меня имеет хитрую структуру с разными пересекающимися областями, там черт ногу сломит.
Но у нас же есть слои! Долой рутину с оперных подмостков!
Итак, к черту запоминание фонов и все вот это. Будем выводить спрайты анимации на СРЕДНИЙ слой экрана. Это позволит нам не запоминать никаких фонов, а просто стирать выведенные спрайты прямоугольниками с заливкой прозрачным цветом. И выводить спрайты тоже можно прямоугольниками — никаких тебе BIC по маске и BIS. Правда, на этом слое у нас обитает Дейв — ну и выселим его на верхний слой, там ничего кроме обоймы с патронами нет. Интересно, может ли Дейв допрыгнуть до обоймы? Да, может, как выяснилось. Есть такие места. Ну и ладно, пусть об этом думаешь Тэд из будущего.
Вывести анимацию на средний слой — это шикарное избавление от кучи проблем. Но ведь они должны быть привязаны к фону и двигаться вместе с ним. И тут пригождается независимый скроллинг слоев. Не эти ваши всякие паралаксы же реализовывать ими! Делаем средний слой всего одним квадратом 512х512. Видимая часть у нас 256х192. Синхронизируем это с нижним слоем так, чтобы средний слой всегда имел запас по краям со всех сторон видимой области — это позволит выводить анимацию в еще невидимые области на границах отображаемой части, чтобы объекты могли входить в кадр справа-слева-сверху-снизу и при этом не надо было заботиться об обрезке спрайтов границами экрана. Нижний слой, состоящий из кучи страниц, переключает скроллится в одну сторону, над ним второй слой перематывает сам себя и все время начинается на координаты -200 по X и -140 по Y относительно рабочего окна. Над всем этим стационарно висит слой с Дейвом без всякого скролла. Трехмерная модель высылается по запросу (шутка).
Процесс синхронизации занял у меня довольно много времени, так как я наткнулся на непонятную проблему — при спуске вниз анимация внизу экрана успешно работала, но если Дейв поднимался чуть выше и слой двигался, то в нижней трети экрана спрайты анимации вообще исчезали. Сначала я подумал, что не туда позиционируется вертикальный скроллинг. Потом — что я неправильно задал длину вертикального рулона и поэтому часть строк просто не выводится при прокрутке. Затем начались подозрения на глюк в прошивке AZBK… Наконец, мне пришла в голову гениальная мысль — к черту эти рулоны, надо лечь спать, а то уже два часа ночи.
Как известно, утро вечера всякоразней. С новыми силами и новыми матами я разбирался в этих заморочках с рулонами и координатами и вдруг выяснил, что при выводе спрайта на строки ниже 400 (8) у меня возникает переполнение при вычислении адреса в памяти AZ — там же 24-битные адреса и я на это регулярно натыкался первое время. Ну и вот опять. Спрайты анимации просто переставали выводиться туда, куда надо при определенном соотношении смещения слоя и его виртуального начала относительно фона.
Пофиксил вычисление адреса и все успешно заработало. Записал ролик, выложил его на ютуб и заметил, что теперь не все алмазы мигают как надо 🙂 Но это ерунда, починим!
Сделал вывод анимированных объектов со второго слоя лабиринта — алмазов и прочих бонусов:
Заодно теперь можно открывать шкафы:
А также, провел пару тестов по всенаправленному скроллу для ОБЫЧНОЙ БК0011М, без AZBK. Прикидываю, возможно ли сделать Дейва и для обычной БКшки, ведь все алгоритмы у меня будут. Тесты получились такими (в первом спрайты черезстрочные, во втором полноценные):
Разбираюсь с форматом лабиринта оригинального Дейва — теперь меня интересует второй слой, на котором расставлены все враги, а также все предметы которые можно собрать. Вроде бы сначала идет все хорошо — в дампе коды алмазов (100001) совпадают с кодами шкафов на первом плане, коды Зомби (1) стоят где положено… Дохожу до нижнего уровня и начинаются приколы:
на экране алмаз в шкафу, но в дампе его нет! Там как раз стоит 456 нулей, т.е. это пропуск аж 4 строк и еще 56 элементов
следом за ним на экране большой алмаз (код 20) и в дампе он есть
потом идет пустота, потом код Зомби (1), стоящего у правого края окна
затем начинается уже новая строка и снова код Зомби (1), который стоит у входа в дом
потом код того самого алмаза в шкафу (100001), что на экране стоит ЛЕВЕЕ большого алмаза (код 20)
Ок, допустим что «алмаз в шкафу» кодируется не в той строке, что он нарисован, а строкой ниже, там где «ручка двери шкафа». Тогда понятно, почему они в разных строках с большим алмазом. Но Зомби? Получается, что код 1 — это вовсе не уровень головы или ног Зомби, ведь эти два Зомби на одном этаже, а в дампе — в разных строках. Типа просто вот он тут где-то установлен, строкой выше или строкой ниже. Ставьте его уже сами потом так, чтобы он не торчал наполовину в полу. При этом сам слой практически пустой, ничего не мешало расставить этих Зомби точно по месту, с другими объектами там конфликтов нет.
P.S. Похоже, Зомби кодируются по уровню плеч. А тот, что строкой выше — просто стоит на лестнице, на одну строку выше пола.
Сегодня доделал открытие дверей и переход между локациями:
— «дверь назначения» теперь автоматически выводится открытой при телепортации
— сделана коррекция Дейва в дверь при уходе
— переделано управление бегом, теперь Дейв сразу останавливается, если отжата клавиша бега на клавиатуре или джойстике. Раньше у Дейва были принцевские замашки, т.е. движение должно было доиграться до конца
Потихоньку пополняю список того, что можно добавить или исправить в Goonies:
— задание кнопок паузы и меню на джойстике
— сохранение настроек игры на диск
— публикация рекорда и открытых секретов по сети (если обнаружен AZBK)
— исправить затирание части «табло» максимально набранным шмотом
— исправить провал сквозь пол (Alex Shestipaloff снова умудрился провалиться)
Итак, чтобы было понятно в чем суть, объясню как устроен вывод лабиринта в Дейве (моем). Хранится он, конечно, в виде кодов объектов, но его ведь надо вывести на экран. Причем экран в Дейве скроллится во все стороны с произвольным смещением, значит надо или постоянно дорисовывать невидимые части и вдвигать их в видимое окно, или вывести сразу весь лабиринт тайлами и только двигать по нему окно отображения. Во втором случае рисовать больше ничего не надо, только смещай окно да и все. Как угодно можно смещать.
Тут начинаются (как обычно) ограничения.
В контроллере AZBK можно вывести на экран любую область его памяти, просто указав «экран начинается с такой-то страницы».
В контроллере AZBK максимальная длина строки для экранного отображения — 512 байт. Для используего в Дейве видеорежима (256х192, 256 цветов) это байт на точку. Значит, рисовать «полотно» можно только кусками 512х512, а не каким-то там гигантским холстом.
Скроллинг окна есть аппаратный, как горизонтальный так и вертикальный. Это прекрасно. Но он сворачивает окно в кольцо. Т.е., если мы двигаем окно влево, то справа вылезает начало этого же самого окна. Хорошие новости — размер окна может быть 512х512, а видимая часть у нас 256х192. Значит, мы можем протянуть 256 «новых» точек рулоном из невидимой части. Но после этого все равно в окно вползет левый край этого же, пусть и большого, окна.
Каким же образом двигаться по большому холсту? Можно в невидимой части дорисовывать новую обстановку. Но Макс (MaxiolLtd) предложил идею покруче: «У нас же море памяти! Можно сделать кучу страниц и оперировать ими!».
Т.е. мы делаем две страницы 512х512 таким образом, что вторая страница ПОВТОРЯЕТ половину первой. И тогда, когда горизонтальным скроллом мы втянем влево эти правые 256 точек, мы может сбросить счетчик рулона на ноль, а начало экрана для отображения переключить уже на вторую страницу 512х512. Ведь у нас эти два куска по 256 точек полностью совпадают. И таким макаром двигать можно бесконечно — половину вкручиваем, перключаемся на следующую страницу. Расход памяти дикий, олды бьются в истерике «это не наш метод», ну да и пофиг, развлекаемся 🙂
Коряво нарисую как выглядит «мегаэкран» в моем ремейке Дейва:
Специально сдвинул квадратики, чтобы они не затерли границы друг друга. В целом, понятно, как это выглядит — по вертикали тоже надо продублировать половины (много половин, много, да).
Скролл заработал весело, но чуть позже стало понятно, что везде есть подводные камни — если на пересекающихся частях нужно что-то изменить (открыли дверь, к примеру), то ведь и скопировать теперь надо эти изменения на ВСЕ пересекающиеся части. Итого может быть от 1 до 4 копий одного места.
Вот тут и начались развлечения с дверями. Дело в том, что эти виртуальные видеостраницы 512х512 тоже состоят из страниц, которые имеют фиксированный размер 10000(8) байт. Блиттер, конечно, лихо рисует на них, ему только адреса подкидывай. 24-битные. Но надо еще и все «соседские отношения» помнить — кто на ком стоял. Причем, размеры у лабиринтов у всех разные, окошек 512х512 может быть разное количество и по вертикали и по горизонтали. Поэтому двери у меня два или три дня появлялись непонятно где (неверно считались смещения на соседних страницах), потом вроде открываешь дверь, идешь от нее, а она у тебя за спиной закрывается! Страница включилась с неоткрытым вариантом. Ну и все в таком духе.
Записал видеоролик, залил в ютуб и потом там заметил, что на 1:31 там мелькает снова закрытая дверь! Начал думать как это снова могло произойти и понял, что не учел того, что дверь имеет размеры 2х3 тайла и при этом может стоять на границе аж четырех страниц! Т.е. левая часть в одном окне, правая часть в другом, а нижняя половина еще черт знает где.
Но сегодня я их добил! Теперь можно в эти шкафы что-то и поставить. Ролик исправлять уже не стал, пусть останется для истории:
Свежие комментарии