Сетки

RobustToolbox имеет поддержку тайловых карт на уровне движка, называемых сетками (игроки SS14 также могут называть их шаттлами или станциями).

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

Коллизия сетки

Сетки используют тот же код физики (box2d), что и всё остальное. Сначала вам следует почитать о том, как работает box2d.

Мы генерируем фикстуры для каждого чанка и прикрепляем их к телу сетки. При обновлении тайла мы заново генерируем все фикстуры для этого чанка; мы также предпочитаем генерировать фикстуры как можно большего размера, чтобы уменьшить их общее количество. Например, если в чанке 16x16 все тайлы заполнены, то у него будет 1 фикстура размером 16x16. В SS14 это выглядит так:

grids.jpg *Красные линии представляют границы фикстур. Карта SS14 может состоять из сотен фикстур. *В левом нижнем углу виден шов между соседними чанками. Фикстуры генерируются только для каждого чанка отдельно, поэтому не будут больше.

Разделение сетки

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

Для этого нам требуется выполнять поиск пути каждый раз при обновлении фикстур сетки и определять, не отделились ли теперь какие-либо части. Вместо того чтобы делать это для каждого тайла, что было бы непомерно дорого, мы вместо этого превращаем группы тайлов на одном чанке в «узлы» и ищем путь по ним. Весь процесс выглядит так:

  1. Каждый раз, когда чанку нужно заново сгенерировать фикстуры, мы также заново генерируем его узлы. Мы делаем это, заполняя заливкой (floodfill) каждый тайл чанка и возвращая каждый отдельный узел.
  2. Для каждого узла мы определяем его соседей. Они не могут быть на том же чанке, потому что если бы были, то стали бы частью исходной заливки, так что мы проверяем тайлы только на соседних чанках на предмет их узлов.
  3. На этом этапе мы построили граф сетки. На предыдущих шагах мы отметили, какие узлы были грязными, то есть новосозданные и все соседи. Отсюда мы начинаем заливку грязных узлов, чтобы определить, все ли они связаны друг с другом. Если все грязные узлы всё ещё связаны, то разделение невозможно, но если после заливки остались узлы, мы будем постоянно повторять, пока не получим все отдельные группы узлов.
  4. Из вышесказанного мы берём каждую группу узлов и превращаем их в новые сетки. Для этого мы:
  • Создаём новую сетку и применяем позицию + данные физики старой сетки (например, её скорость)
  • Устанавливаем все тайлы на новой сетке
  • Для каждого тайла проверяем любые закреплённые сущности и заново закрепляем их на новой сетке. Поскольку новая сетка имеет ту же позицию и поворот, что и старый родитель, нам нужно позаботиться только об обновлении родителя.
  • Для каждого тайла проверяем любые незакреплённые сущности и заново привязываем их к новой сетке.
  • Устанавливаем все файлы на старой сетке пустыми.

Отладка

Команды

showchunkbb Переключает показ всех фикстур сетки во вьюпорте.

showgridnodes Переключает видимость узлов сетки, используемых для проверки разделения. Также включает связи между узлами.

Subpages