Подгружаемая карта в игре с несколькими точками загрузки, как избежать коллизий и объединить соседние элементы
Карта лежит в базе данных, достается она оттуда кусками 16х16(Chunk).
Есть статичный класс карты Map.
В текущий момент в игре реализован загрузчик чанков ChunkLoader. Он отправляет Map координаты объекта, около которого нужно прогрузить карту определенного радиуса(для простоты возьмем 3х3).
Загруженные Chunk'и сохраняются в четырехсвязный список QuadList(ну или графы, принцип тот же: ссылки на соседние элементы). Выбрана данная структура из-за удобства добавления и удаления элементов по краям. Хранятся в оперативной памяти только ссылки на крайние элементы(4шт, по углам).
Вроде бы все работает хорошо, но вот возникает проблема: при добавлении еще одного ChunkLoader'а прогруженные Chunk'и могут начать пересекаться, следовательно Map будет отрисовывать одни и те же куски, если иметь отдельный QuadList на каждый ChunkLoader. Но это не так страшно, хуже всего то, что непонятно как реализовывать теперь логику перемещения объекта, поиск пути.
Вопрос состоит в том: как модифицировать текущую структуру хранения прогруженной карты, чтобы исключить коллизии одинаковых Chunk'ов? И сделать возможным следующее: соседние Chunk'и должны быть связаны независимо от объекта, ChunkLoader которого вызвал прогрузку этих Chunk'ов. Если они не пересекаются и не граничат, то соответственно никак не связаны.
Ответы (1 шт):
На скоько я понял, под колизией вы имеете в виду, что два лоудерс пытаютсч заспавнить 2 чанка в одном и том же месте, подобно тому как две переменные записываются в одну и ту же ячейку хеш таблицы.
Из чего следует, что должен быть менеджер лоудеров организующий взаимодействие, коим может быть Map или нет. Алгоритм спавна чанка у лоудер:
- 1)
void RollChankFromSpawn()лоудер выбирает от какова чанка спавнить (скажем чанк с координатой 9х7) - 2) выбирает кондидата из пустых координат по соседству (пускай 10х7)
- 3)
void PrepareSpawnOnTile(Vector2 tile, bool checkEmpty)собирает инфу о соседних, о 9х7 уже знаем, но в чанке могут храниться и другие (допусти ещё 10х6) - 4) ещё 2 "пустых" (11х7 и 10х8) которые могут быть частью других чанкоч, поэтому спрашиваем у менеджера лоудеров
ChunkLoader HasChunkOnTile(Vector2 pos)выдай лоудер с чанком по этой координате для обоих. - 5a) если оба ответа от менеджера null, то
void SpawnChunkOnTile(Vector2 tile). - 5b) если нет, говорим менеджеру объединить лоудеры
void ConnectLoadersAndSpawnChunkOnTile(ChunkLoader[] loaders, Vector2 tile). В массиве сам лоудер который хотел спавнить и остальные не повторяющиеся лоудеры, оказавшиеся в "пустых" позициях (может получиться до 4) и куда мы будем спавнить сразу с пункта 3) без 4) после обьединения (поглащения одним лоудером, списков чанков и QuadList'ов остальных). Заодно решит проблему поиска путей.