| Разработка и ромхакинг > Ромхакинг и программирование |
| Хитбоксы в 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. Добавить его равномерности сложнее. Всё это планирую осуществить в следующей части, если будет. |
| Навигация |
| Главная страница сообщений |