TDS: теперь более развернуто
В прошлый раз мне посоветовали делать более подробные посты, чем я сейчас и займусь.
По поводу раскрытия темы: какое раскрытие? Конкурс закончился уже около года назад, о чем вы?
По поводу геймплея: а вот тут, наоборот, ничего не изменилось. Игра как была шутером с видом сверху, так им и осталась.
Сейчас я в основном занят тем, что наполняю игру контентом, то есть добавляю врагов и оружие. К счастью, это не очень сложно. Если вы помните мой последний конкурсный пост, то в нем я писал, что методика создания оружия у меня не очень гибкая, и хотелось бы сделать ее гибче. Так вот, это мне удалось, еще в прошлом году, причем решение данной проблемы — старый-добрый принцип «предпочитайте композицию наследованию» — лежало на самой поверхности, я только не совсем знал, как его применить.
Теперь же, вместо того, чтобы создавать подкласс пули каждый раз, когда мне от нее требуется какое-либо новое поведение, я просто создаю новый компонент и «прикрепляю» его к пуле. У пули же есть несколько массивов с компонентами: одни вызываются каждый кадр, другие — при столкновении, третьи — при смерти
С этими проблемами я пока справляюсь, но в следующий раз точно буду использовать другую архитектуру.
Самонаводящиеся ракеты. Они используют два основных компонента: один кренит их то влево то вправо, делая траекторию «пьяной"(тот же компонент используют и враги, кстати), а второй, собственно, отвечает за самонаведение. За взрыв при попадании тоже отвечает компонент, причем он всего лишь выстреливает оружием, которое создает сам взрыв.
Эти враги отражают пули обратно в игрока. Сами понимаете, что использование самонаводящихся ракет против них равняется самоубийству.
Оружие бывает двух типов: автоматическое, выпускающее пули с определенным интервалом, и «заряжающееся», заряд которого повышается с удержанием кнопки мыши. При отпускании мыши заряд передается коллбэк-функции, которая уже и спавнит пули. Можно заспавнить больше пуль. Или повысить их урон. Или вообще менять их на другие. Ограничением является лишь воображение.
Из основных запланированных фич мне осталось лишь реализовать волны, которыми будут спавниться враги и магазин с оружием. Я говорю «лишь», но скорее всего это займет еще много времени, особенно учитывая, что я часто прокрастинирую, или возвращаюсь с работы выжатым, как лимон, так что мотивации ни на что не остается.
Но я справлюсь. Скорее всего.
- 15 сентября 2019, 23:12
- 08
Компонентная система для пуль - хорошая идея (в основном), но мне вот интересно, как обычно с этим работают в рантайме. Особенно если пули организованы пулом (хаха). Получается, перед выстрелом нужно "конструировать" новый снаряд. Мне просто интересно (как человеку, который скоро сам будет такую систему пилить), как это в плане производительности работает, и какие оптимизации для этого существуют.
Да, приходится создавать новые пули каждый раз, но проблем с производительностью пока не возникало. Есть вроде такой шаблон, который может быть полезен: https://gameprogrammingpatterns.com/flyweight.html
Если пули организованы пулом, то зачем что-то конструировать перед выстрелом? Или я чего-то не пони
Пули не организованы пулом, так что при каждом выстреле приходится создавать новые. Но за кадр в среднем создается лишь пара штук, так что пул тут не особенно-то и нужен. Другое дело - частицы, для них я пул реализую, но даже тут для производительности проблему составляет скорее не аллокация памяти и работа сборщика мусора, а рендеринг.
В любом случае пуля должна иметь вполне конкретный набор компонентов на момент выстрела, и не важно, вышла ли она с пула или создана с нуля. Вот мне и интересно, как это обычно работает для пула. Я взял апгрейд на автонаведение снарядов на врагов. Мне сразу вешать этот компонент на все инстансы пуль игрока (в том числе неактивные), или в момент вытягивания пули из пула? А если апгрейды еще и отменять можно, то компоненты аналогичном образом надо убирать.
В принципе, наверное, лучше всего сразу вешать/убирать на весь пул, просадка по производительности может быть, но ее можно замаскировать под анимацию апгрейда.
Насколько я знаю, если у тебя труъ-компонентно-ориентированный движок, то он использует пулы для компонентов, а пуля, т.е. сущность, остается лишь в виде свойства компонента.
Не знаю, как это делают умные дяди, но по идее "автонаведение" это объект, реализующий поведение. Завязываемся на какой-нибудь интерфейс/протокол IBehavior, при добавлении пули на игровое поле устанавливаем ей объект поведения на нужный (который берём из текущей конфигурации игрока/уровня/проч.).