Поговорим о траве. Дневник разработчика ThN World №2

Начну с того, что я хочу добавить в игру в первой же локации довольно много травы, а остальное в статье.

Поговорим о траве. Дневник разработчика ThN World №2

Что из себя должна представлять трава:
- 4+ разновидности анимированной травы
- Если игрок наступает на траву, она должна сминаться.
- Если игрок уходит с травы, трава восстанавливается.
- Добиться максимальной оптимизации.

Если создавать подобный объект в годот, реагирующий на игрока, каждый блок травы (БТ) должен быть отдельной нодой, объектом, Каждой ноде надо задать координаты, что займет очень много времени, В добавок, каждый кадр каждый БТ будет отслеживать, не вступил ли игрок в его зону... Еще и делать это будет на всей карте. Звучит не очень оптимизировано, не правда ли?

50 объектов  травы на 50 шагов персонажа
50 объектов  травы на 50 шагов персонажа

И как же быть?

Предположим, у нас уже есть 4 разновидности травы, и для каждой мы имеем анимации Idle, прижатия, раскрытия. Всё это дело уложено в одну ноду. В таком случае создадим тайлмап, в на котором мы разместим для начала всю траву без анимации. После чего скроем ее, сделав невидимой.

Поговорим о траве. Дневник разработчика ThN World №2

На данный момент, в игре мы имеем не анимированную траву да еще и невидимую, что дальше?

В годот к тайлмапу можно использовать метод get_used_cells(layer), благодаря нему мы можем в переменную поместить список всех занятых тайлмапом ячеек. А после сортировки этого массива по оси x получим крайне полезный инструмент.

Координаты всех занятых в тайлмапе ячеек.
Координаты всех занятых в тайлмапе ячеек.

Теперь, когда у нас есть буквально координат карта, и сам БТ всех видов трав, приступим к размещению анимированной травы и оптимизации.

Пул объектов

Если мы хотим в оптимизацию, мы не можем себе позволить просто взять и при запуске уровня загрузить всю траву одновременно. В этом случае это ничем не будет отличаться по от шакального способа размещения объектов в начале статьи.

Предзагрузим на уровне 30 БТ помещенных в массив, которые будут загружены с запуском уровня, где-то за картой, и они будут стоять на паузе. Таким образом они просто будут храниться в оперативной памяти не нагружая процессор. Дальше напишем функцию, которая при движении игрока будет отслеживать, какие ячейки нашего тайлмапа находятся в радиусе видимости игрока. Находим ячейки через самый простой for, телепортируем туда траву из-за карты, и снимаем с паузы. И всё. Трава будет видимой только в определенной зоне от игрока. Если игрок уйдет далеко от травы, она просто вернется обратно за карту.

Таким образом, вместо 1000+ БТ травы которая может быть на уровне, у нас постоянно в памяти будет храниться и работать всего 30. Тем самым мы избегаем утечки памяти, и снижаем постоянную нагрузку на цп.

Спрашиваем у тайлмапа, какой вид травы находится на видимой ячейке и говорим ноде с БТ включить нужный вид анимации.

Спрашиваем у игрока, на какой ячейке он стоит, и ставим ей анимацию прижатия.

Дальше больше.

Давайте оптимизируем еще сильнее. Сделаем так, чтобы при движении игрока, игра проверяла не все заполненные ячейки тайлмапа, а только те, что находятся на границах видимости.

Создадим переменную min и max, в которую при запуске уровня поместим координаты крайних ячеек. Теперь при смещении вправо и влево, нам надо проверить только ячейки которые находятся рядом с min и max. Если у вас действительно 1000 травы на уровне, проверка 9 ячеек будет на много лучше чем 1000
Сверху добавим:
- Проверка осуществляться будет не каждый кадр а при смещении на 3 шага.

Поговорим о траве. Дневник разработчика ThN World №2

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

Пожалуйста, укажите на недостатки статьи сколько бы их не было. можете даже сказать "это не интересно". Хочу знать о чем говорить.

10
16 комментариев

Чем хорош годот, так это возможностью одну и ту же задачу решать разными способами. Как ты решил с координатами, можно аналогично через сигнал для узла Area2D. Интересно было бы посмотреть в дебаге на график выделяемой памяти, но у меня нет похожего проекта, чтобы проверить. Попробую как-нибудь.

Респект за выбор годота. В дефолде это накостылить было бы сложнее.

1
Ответить

Кстати да. Area2D можно было бы попробовать привязать к персонажу. Возможно был бы проигрыш по оперативной памяти. Мне кажется в таком случае нужно было бы прогружать всю траву при запуске и ставить на паузу. А хотя...

нода с травой у меня весит 11 кб, даже если ее умножить на 1000 блоков, в крайнем случае вся трава на уровне будет занимать 11-12 мб оперативной памяти. Другой вопрос к цпу, он будет нагружен сильнее, но как мне кажется, это до смешного небольшая разница.

Ответить

...не остаться в этой траве...

Ответить

надо будет что-то запрятать в траве чтобы игроки зае*ались искать XD

1
Ответить

Симпатично получается, хотя метод с присваиванием / хранением и анализом координат мне кажется малость топорным - точно в годоте нет встроенного способа обрабатывать только объекты в кадре, а остальные оставлять в айдле?

Ответить

А хрен его знает. Единственное что я заметил, так это то что по отладке , мне удалось оптимизировать траву до такого уровня что она перестала понижать производительность вовсе. Изначально она сильно нагружала, а теперь перестала вовсе. Так что топорность метода позволяет выйграть в оперативной памяти, загружая всего 30 травы на уровне, а не всю. И не нагружает процессор, так как запросов приходится минимум.

Ответить

Мне кажется что даже если и есть метод, то вся трава на уровне все равно будет храниться в оперативной памяти, а если нет, то игра будет постоянно подгружать и выгружать из памяти траву при перемещении. Что тот, что другой вариант не очень хорошо выглядит. Мне кажется только пул объектов может достичь желаемой оптимизации.

Ответить