Войти
ПрограммированиеФорумОбщее

Вопрос о хранении, учёте и процессинге противников на уровне.

#0
(Правка: 4:05) 4:03, 12 янв. 2022

Пишу игру на голом Си под SEGA MegaDrive.

Реализовал в игре несколько противников. Есть функционал для:

1. Создания и инициализации противника
2. Процессинг противника (+ его AI, для сложных случаев)
3. Заморозка и удаление противника

Кадр - 320x224 пикселя.
Если противник полностью уходит за кадр, его спрайты становятся невидимы, но его процессинг(логика, AI) работает
Если противник ушёл за удвоенный размер кадра (область более 640 пикселей в ширину и 448 пикселей в высоту), то он уничтожается.

Пока противники находятся в фазе тестирования: хардкодом в программе инициализирую поля структуры Enemy.

В целях упрощения, пускай у противников имеются следующие поля:

1. X-координата появления
2. Y-координата появления
3. Число HP.  Еcли HP<=0, потивник умирает
4. Флаг Live.  Если =1 - противник активен,  если =0 , то умирает(не показывается)

Координаты камеры  -ScrollX, ScrollY.

Число противников (максимальное) на уровне пускай будет 50.
Размер игрового мира уровня:  25x6 кадров.

Ресурсы:

ROM 4 МБ максимум - память доступная только на чтение. В ней хранятся начальные данные противников

RAM 64 кБ, из них допустимо использовать 25...50% от всего объёма.  В ней будут храниться данные тех объектов, которые могут меняться со временем.

А теперь собственно вопросы:

1. Как организовать хранение данных противников в ROM ? Кроме X,Y,HP,Live  будут ещё параметры, специфические для конкретного вида противника, и они весьма разные.

2. Как сделать механизм появления тех противников, которые попадают в камеру, и отсечения тех, кто за пределами ?

3. Как реализовать механизм подкачки противников из ROM в RAM?

Вот такие непраздные вопросы.
Был бы у меня ПК,  я бы даже и не задавал вопросов тут.

А так SEGA с её 64 кБ оперативы, выводит  меня на жёсткий ресёрчинг в условиях ограниченных ресурсов.

Пишем любые умные идеи!


#1
5:21, 12 янв. 2022

Gradius
> А так SEGA с её 64 кБ оперативы

А разве не было возможности "апгрейда" приставки путем впаивания в картридж дополнительной памяти?

#2
6:37, 12 янв. 2022

mingw
> А разве не было возможности "апгрейда" приставки путем впаивания в картридж
> дополнительной памяти?

Это сделать можно. Но для меня это будет реальной пощёчиной, что не смог обойтись только штатными ресурсами.
Хотя технически, это сделать очень легко - оттяпать диапазон адресов из ROM сколько надо, или привешать на резервное окно адресов ( в СЕГе этого добра валом).  Правда, эмулятор придётся немного доработать.  Или не доработать - будет защита от дампинга картриджа.

Поэтому хочется пока решить задачу штатными средствами сеги.

Вот что интересное по теме нашёл: https://www.pvsm.ru/dendy/257217
Внутренняя структура игры Contra.

Наверное Гульдефир подсказал бы многое по этой теме...

#3
9:25, 12 янв. 2022

> на уровне пускай будет 50.
Нет. Пулл противников 10-15. А потом обновляется в процессе. Ведь учет идет на то, что ты дальше текущего кадра не пройдешь.

#4
(Правка: 4:19) 4:12, 14 янв. 2022

lookid
> Нет. Пулл противников 10-15. А потом обновляется в процессе. Ведь учет идет на
> то, что ты дальше текущего кадра не пройдешь.

Так и сделал.

Ввёл понятия RAM-кеша - тот самый пул, который хранит отображаемых противников. К примеру - 4 максимум.
А в ROM хранятся все противники на уровне. К примеру - 50.

По координатам скрола Scroll X,Y и габаритам экрана 320x224 вычисляется область работы противника (с небольшими зазорами со всех сторон: к примеру 128).

Далее в RAM-кеше находится свободная строка(запись) куда можно скопировать данные противника из ROM в RAM.
Часть данных: начальные координаты противника, их тип, некоторые параметры - берутся из ROM.
А другие данные - число хитов и признак что противник не убит - инициализируются самой игрой сразу в RAM.

В процессе игры, противники пересоздаются в RAM (каждый раз при пересоздании могут занимать разные строки в RAM-кеше), если не были убиты игроком.  Если игрок убил противника, то он помечается особым значением, чтобы более не пересоздавался.

Причём, для противников введено понятие первого их создания: когда начальное число HP присваивается игрой. А при повторных пересозданиях, число HP берётся из записи в RAM (перед удалением противника идёт запись актуального HP в RAM).

Связь кеша RAM и данных ROM идёт через ID - это есть индекс массива данных в ROM.

Введено понятие валидного ID. Если ID = -1 , то строка RAM-кеша свободна, можно занимать. Это же ID=-1 служит для освобождения строки кеша противников, когда противник убит или скрывается из активной области.

Если игрок снесёт противнику некое число HP, то это тоже фиксируется: при пересоздании противника число HP берётся то, которое актуальное последнее.

В общем, как-то так сделал. Всё работает. Вопрос решён!

P.S. Аналогично работают пули, взрывы, спрайты и другие объекты в игре - перед постановкой в очередь, ищется свободное место.

ПрограммированиеФорумОбщее