Разработка и ромхакинг > Ромхакинг и программирование
Хитбоксы в Shmup играх
(1/1)
Segaman:
кто разбирал игрухи в этом жанре, помогите.
как олдовые ретро игрули чекают хитбоксы тратя при этом минимум ресурсов?
яркие примеры: zanac, gradius, super spy hunter
на экране иной раз летают десятки пуль и при этом почти всегда поддерживается высокий фпс.
однако если писать полную проверку хитбоксов всех объектов, ресурсов на это тратится несоизмеримо много и фпс проседает уже от 10+ объектов.
еще можно например на Contra посмотреть, в играх этой серии пуль на экране тоже много, а производительность при этом не падает.

вопрос: к каким хитростям прибегают ретро игры, чтобы поддерживать высокий фпс при большом количестве пуль на экране?  :neznayu:
mishra:
Единственное что пришло в голову - при обработке пары объектов один из них задать не хитбоксом, а одной точкой. Попадание точки в хитбокс обработать проще чем столкновение двух хитбоксов.
Sharpnull:

--- Цитата: mishra от 26 Август 2019, 17:15:12 ---при обработке пары объектов один из них задать не хитбоксом, а одной точкой
--- Конец цитаты ---
Очевидно же.
Segaman, Например, у Contra (Retro Game Internals: Contra Collision Detection) оказалось почти стандартно. Флаги для определения что с чем сталкивается, на все пули игрока и самих игроков проверка в обновлении врага. Но интересно столкновение врага с игроком и пули врага с игроком: у игрока точка, а у вражеских объектов прямоугольники, которые меняют форму в зависимости от положения игрока (стоит, в полёте, лежит). Это эффективно, потому что проверка всегда точка с прямоугольником. Для пуль игрока у врагов тоже есть разные прямоугольники. Правда я не до конца понял почему это эффективно.

Наверно у шмапом также. Точка против прямоугольника. Вражеские пули не сильно усложняют, потому что проверяются только с игроком. А вот с пулями игрока нужно быть поосторожнее.
--------
Если подумать, в Space Invaders и Galaxian враги встают в сетку не просто так, можно эффективно проверять столкновение: сначала с общим прямоугольником врагов, после относительно него проецировать пулю на массив + небольшое смещение, когда она летит между.
DrMefistO:
Решается всё так: https://stackoverflow.com/questions/2752349/fast-rectangle-to-rectangle-intersection
Насколько я помню, в Thunder Force 3 делалось пересечение ректанглов. Если пересекается - значит есть попадание. Почему это должно тормозить для числа объектов в районе 10, например?
Segaman:
Sharpnull, спасибо за подсказку.
я попробую применить нечто подобное, но я уверен, что успех обеспечен.
я видел в коде ContraHard Corps нечто подобное, но я не понял принципа работы всего этого.
теперь с пониманием этого секрета мне станет легче реализовывать эту технику. :cool:

что я попробую сделать:
1) помещу игроков в первый список, объекты во второй, пули врагов в третий и пули игроков в четвертый.
каждый объект будет проверять только свой список.
2) добавлю в игру 3 стека (обьекты, пули врагов, пули игрока)
3) каждый объект, пока существует, будет добавлять указатель на себя туда и в то же время список будет очищаться каждый кадр. это позволит проверять только активные объекты и игнорировать пустые ячейки и неактивные объекты.
4) проверять хитбоксы с точкой, вместо двух квадратов. будет несложно составить таблицу таких хитбоксов

Добавлено позже:
DrMefistO, потому что у меня проверяются 128 ячеек объектов и если ячейка занята идет проверка что за объект и тд.
куча ненужной тягомотины.
я отчетливо помню, как в Contra Hard Corps применялось нечто отличающееся от того, что я привык видеть, а когда столкнулся с проблемой не смог ее решить сам, вот и обратился за помощью к знающим людям.  :)

Добавлено позже:
тем более, что лагать вообще ничего не может, ибо я даже id объектов не использую для получения указателя на исполняемый код этого объекта. вместо этого у меня есть этот указатель прямо в памяти самого объекта, а id служит лишь для идентификации объектов между друг другом.
это удобно потому что:
1) процессор не лезет в ром за таблицей и не проводит лишних телодвижений с умножением (смещением бит) и чтением из таблиц
2) процессор тратит минимум циклов на запуск кода объекта
3) всегда можно без всяких switch и условий поменять callback и поведение объекта тут же изменится.
4) всегда можно определить паттерны поведения объектов и присваивать их вне зависимости от id объекта. например: объект преследует игрока. это может быть враг, а может быть броня. неважно, потому что callback у них один и тот же, а вот id разные и от врага мы получим урон, а от брони и так  ясно что. :lol:
DrMefistO:
Если объект видим, или жив (флаг установлен в байте блока объекта), то чекать, иначе переходить к следующему.
Segaman:
DrMefistO, так медленнее :)

Добавлено позже:
забыл сказать, что указатели на объект у меня хранятся в 2 байтах, что еще сильнее ускоряет процессы
DrMefistO:
Это я тебе пересказываю по памяти, как было в TF3.
mishra:
С вашего позволения продолжу капитанить  ;) : Попадание точки в ректангл происходит при выполнении четырёх неравенств. Проверяем эти неравенства по очереди и при первом же невыполненном завершаем проверку. Таким образом обработка пары объектов в большинстве случаев закончится после одного-двух сравнений чисел. Тут ещё можно поиграться с порядком проверки чтобы на первых неравенствах отбрасывалось побольше объектов.
TiberiyLTim:
DrMefistO, я сделал "Star J" с просчетом прямоугольников... И это значительно тормозилось, т.к. приходилось обрабатывать для каждой пули игрока столкновение с каждым противником.

Как я понял, эффективнее будет если каким-либо образом добиться материнства одинаковых объектов и клонировать обработку, разбив на цикл. Ну и проверка объекта только, если он активен (Enemy1=1), само собой. Но тут будет прыгать fps. Добавить его равномерности сложнее. Всё это планирую осуществить в следующей части, если будет.
Навигация
Главная страница сообщений

Перейти к полной версии