Монстры обзаводятся интеллектом
Переделал вывод анимации очков на двухстраничный экранный режим. Начал делать обработку обстановки монстрами (поиск препятствий, ям, лестниц).
Блог разработчика
Переделал вывод анимации очков на двухстраничный экранный режим. Начал делать обработку обстановки монстрами (поиск препятствий, ям, лестниц).
Все очень просто:
И никаких проблем.
Наконец-то я победил эти «хвосты» при скроллинге! Можно делать игру дальше!
При больших сдвигах рулона среднего экранного слоя (где бродят Зомби) промелькивали объекты, которые должны были уже быть стерты. И борьба с ними заняла у меня три дня…
Пока я использовал блиттер в атоматическом режиме (он при этом сам стартует при каждом прерывании по вектору 100) — все было почти хорошо. Точнее, в эмуляторе было вооще все хорошо, а вот на реальном железе при глобальном скроллинге экрана иногда наблюдалось какое-то дергание экрана. Этим, конечно же, было поручено заняться Тэду из будущего. При этом возникал вопросы о скоростном построении экрана из множества тайлов — ведь количество команд, которые можно скормить блиттеру за раз, ограничено. А это значит, что лабиринт будет заполняться порциями, каждыя из которых будет выводиться при очередном прерывании по вектору 100 («кадровое»). С появлением в AZBK режима ручного запуска блиттера, эта проблема ушла — выдаем блиттеру пакет за пакетом и запускаем все это сами, не ожидая милостей от вектора 100. Заодно появилась возможность сбрасывать блиттеру фоновые задачи, типа «удали старые спрайты со скрытого экрана, а мы в это время посчитаем куда какому монстру сделать шаг». И вывод на экран стало возможно делать тогда, когда хочется, а не ожидая очередного «кадрового» прерывания. Вот тут и был подвох.
Как только я добавил Зомби, шагающих туда-сюда, потребовалось их еще и скроллить вместе с фоном, когда Дейв инициирует движение окна. При этом, когда скроллинг (вертикальный или горизонтальный) докручивался до максимума и надо было уже переключать окно, вдруг могли промелькнуть какие-то дополнительные фигуры Зомби, там, где их никак быть не могло. Я предположил, что это спрайты, которые не успели стереться, а это место экранной страницы было вытащено скроллингом на видимую область экрана. Стало ясно, что эти вещи надо тоже теперь синхронизировать вручную — сдвиг рулонов и переключение видимой области экрана. Но когда пакет команд блиттеру ушел, то о том, что блиттер его обработал, можно судить только по биту 15 в регистре 177270. Т.е. надо ждать, когда этот бит сбросится в 0 и потом можно переключать рулоны.
А рулоны двигаются совсем в другом месте — в подпрограмме перемещения слоев в зависимости от деятельности Дейва. Блиттер работает сам по себе где-то в фоне, а вот регистры скроллинга изменяют изображение сразу. Значит, нам в этой подпрограмме нельзя изменять сами регистры, нужно просто вычислять новые значения, чтобы применить их потом, сразу кучей, после того, как блиттер закончит стирать/выводить спрайты и все будет готово к отображению нового кадра. Причем желательно это сделать как раз в момент обратного хода луча, чтобы было незаметно.
В итоге, я завел несколько переменных, содержащих копии регистров управления слоями экрана и движок теперь изменяет не сами регистры, а эти переменные. А перенос значений из этих переменных в сами регистры происходит в тот момент, когда все готово и блиттер завершил обработку команд.
Вот тогда призраки и были изгнаны и «дрожь земли» пропала!
Да, еще я напоролся на небольшие грабли: если пакет команд маленький, то блиттер так шустро его выполняет, что бит 15 (признак работы блиттера) и установиться не успевает. И это приводило к бесконечным ожиданиям «когда ты там начнешь команды обрабатывать??» и зависаниям.
В цикле вывода на экран стоял wait и сам вывод начинался после возникновения прерывания по вектору 100 («кадровое прерывание» на БК). Это необходимо, чтобы спрайты не мигали на экране, ведь их приходится стирать и выводить снова, и момент, когда спрайта нет на экране не должен быть виден игроку. Но это самое ожидание обратного хода луча может все и тормозить, если программе есть чем заняться 🙂 Альтернативой является использование двух экранных страниц — одну страницу скрываем, стираем на ней спрайты (все равно она не отображается сейчас), выводим заново на новых местах, а в это время демонстрируем вторую. Таким образом момент, когда спрайты стерты, не виден.
На БК0011М экранных страниц две. А сколько их на AZBK? Да сколько хочешь, ведь вся память AZBK может быть отображена с любой страницы. И включать эти страницы можно в любые слои экрана. Вот я и завел себе две экранных страницы для верхнего экранного слоя и вывожу туда бегущего Дейва, попеременно включая то одну, то вторую. В итоге ожидания обратного хода луча нет и мигания спрайтов тоже нет.
Завтра заведу две экранных страницы и для среднего слоя, где Зомби гуляют.
Переделал движок анимации монстров. В анимации Зомби каждая фаза движения стоит на экране 8 кадров, напрашивалось решение выводить на экран только один из этих спрайтов, первый. А потом 7 кадров пусть он себе стоит, не надо выводить его заново. Что и было реализовано. Получен, конечно, большой выигрыш в скорости обработки монстров. Но можно еще ускорить, если сдвинуть начальные фазы монстров так, чтобы они обновляли свои ключевые спрайты не одновременно.
Не обошлось без подводных камней: пакет команд в блиттер уходит сразу после получения «кадрового» прерывания, а вот изменения начального адреса отображения слоя видеопамяти — в процессе обработки скроллинга движком. В итоге иногда на экране мелькают призраки Зомби, которые не успели стереться. Идеи борьбы с этими «хвостами» у меня есть, завтра попробую реализовать.
Монстров на одном уровне в Дейве прямо толпы — количество их достигает 60 штук. Конечно, не все они видны и в реальной игре Дейва быстро сожрут при большом столпотворении, но все равно есть что оптимизировать…
Добавил анимацию Зомби, создал движок для монстров, ошивающихся поблизости. Пока ходят просто туда-сюда, ни на что не реагируя (как зомбированные):
Сегодня плодотворно поработал:
Завтра приступаю к запуску Зомби!
Как-то мне попалось мини-интервью Джона Ромеро, его там спросили под каким углом стреляет Дейв. Ответ был — 45 градусов. Я тогда удивился, почему вообще возник такой вопрос у народа. Поизучал траектории полета пули в оригинале и тоже удивился: что-то там не похоже на 45 градусов никак:
Пришлось немного повысчитывать, но все получилось, теперь Дейв стреляет:
И вот появилось ощущение той самой игры! Теперь надо или подумать над звуками в игре, или заняться монстрами, разлетающимися кусками от них и т.д.
P.S. Совсем забыл — надо же перезарядку дробовика еще сделать 🙂
Добавил анимацию стрельбы и дыма при выстрелах. 6 видов дымов! Один из спрайтов стрельбы оказался с кривым контуром — слишком толстым. Выглядит он как будто с тенью на стене. Поищем, починим. Теперь надо делать обработку попаданий и расход патронов. Гонять стало сразу куда прикольней!
Добавил движения прицеливания. С джойстиком все ок, а вот на клавиатуре придется делать кнопки сразу стрельбы, а не прицеливания. Потому что клавиатура БК не позволяет обработать нажатие двух клавиш. Точнее, есть один способ (через команду RESET), но во-первых работает он только на реальном железе, а во-вторых так вылавливаются далеко не любые сочетания клавиш. И тем более нельзя будет задавать произвольные клавиши для такого метода опроса. Так что от этой мысли я отказался.
Свежие комментарии