Доброго времени суток.
С чем я имею дело: Имеется 2D игра с видом сверху. Карта в игре – тайловая,процедурно генерируемая, размер – бесконечный. Коротко об архитектуре игры: вся игра поделена на четыре модуля – физика, графика, логика, система событий. Эти модули выполняются в одном потоке (далее я буду называть его главным). Каждый объект в игре содержит по одному компоненту физики, графики и логики. Эти компоненты хранятся и обрабатываются соответствующими системами.
Что нужно сделать и какая у меня возникла проблема: Поскольку карта бесконечная – прогружается небольшой участок карты фиксированного размера. При приближении игрока к краям карты – необходимо сгенерировать новые участки карты, а старые удалить вместе со всеми объектами на них. Генерация может занимать до нескольких секунд, поэтому я решил вынести её в отдельный модуль который будет выполняться в собственном потоке. Но у меня возникли трудности с тем, как с точки зрения архитектуры организовать взаимодествие модуля генерации с остальными модулями в игре.
Как я пытаюсь решить задачу: когда персонаж подходит к границе – просыпается поток в котором обрабатывается модуль генерации. Далее модуль генерации начинает генерировать мир, добавляя объекты в спецциальные буфферы предоставляемые модулем физики, графики и логики. Когда генерация завершена, модуль генерации посылает событие в систему событий и засыпает. Система событий, в момент обновления в главном потоке, оповещает логику, физику и графику что генерация завершена. Те в свою очередь меняют местами текущие хранилища на буффера. Я выбрал этот подход, т.к. мы заполняем буффер НЕ ОБРАЩАЯСЬ К ОБЪЕКТАМ в хранилище модуля, что облегчает синхронезацию между потоками; нам не надо тратить время на добавление объектов из буффера в хранилище, а также на поиск и удалени объектов оказавшихся за пределами карты. Исходя из описанного к буфферу предъявляются следующие требования: 1. Буффер представляет собой туже структуру данных, что и хранилище соответствующего модуля. 2. В момент, когда модули получив событие об окончании генерации, меняют местами хранилище и буффер – в буффере должна содержаться только актуальная информация. Нужно учитывать, что в хранилищах модулей из главного потока будут удаляться и добавляться объекты во ремя работы модуля генерации. 3. При приближении игрока к краям прогруженного участка карты – он смещается. Нужно определить, какие объекты остались в пределах карты. Они должны попасть в буффер.
Собственно вопросы, которые у меня возникли: 1. Для хранения динамических физических компонентов используется дерево квадрантов. Как определить, какие компоненты останутся в пределах прогруженного участка карты после завершения текущей генерации, если в главном потоке обрабатывающем физический модуль компоненты могут постоянно добавляться и удаляться? 2. Для хранения различных компонентов логики используются обычные списки. Вопрос тот же, что и выше. 3. Статические физические компоненты хранятся в одномерном массиве чанков. Они распологаются не дискретно относительно чанков и тайлов. Могут быть как очень маленькими, так и очень большими. Вопрос следующий: допустим мы подгружаем новый участок карты и генерируем на нем дом. Дом должен распологаться на границе с ранее загруженным чанком, который сейчас обрабатывается модулем физики в другом потоке. Мы можем добавить дом при условии, что на занимаемом им месте нет ни одного статического или динамического физического компонента. На момент проверки генерации дома это условие соблюдалось и дом был добавлен в буффер. Но модуль физики ничего не знает о модуле генерации и не может згалянуть в буффер, покак не закончится генерация, также будем помнить что динамические и статические физические компоненты хранятся отдельно. Далее, допустим игрок встал на то место, где в буффере находится дом (в главном хранилище это место пустое). И тут генерация закончилась и модуль физики поменял местами буффер и хранилище. Получается – игрок оказался внутри дома не заходя в него. Как решить эту проблему?