Я работаю над системой компонентов сущности для игрового движка. Одна из моих целей - использовать подход, ориентированный на данные, для оптимальной обработки данных. Другими словами, я хочу следовать рекомендациям относительно желательных структур массивов, чем массивы структур. Тем не менее, моя проблема в том, что мне не удалось найти оптимальный способ решить эту проблему для меня.
Моя идея до сих пор заключается в том, что каждый компонент системы отвечает за определенную часть игровой логики, скажем, что компонент Gravity Compal заботится о расчете сил в каждом кадре в зависимости от массы, скорости и т.д. и других компонентов. другие вещи. Следовательно, каждый компонент заинтересован в разных наборах данных. Компонент Gravity может интересоваться массой и скоростью, в то время как компонент Collision может интересоваться ограничивающими прямоугольниками и позицией и т.д.
До сих пор я полагал, что у меня может быть диспетчер данных, который сохраняет один массив для каждого атрибута. Поэтому скажите, что объекты могут иметь один или несколько весов, положение, скорость и т.д., И у них будет уникальный идентификатор. Данные в диспетчере данных будут представлены следующим образом, где каждое число представляет собой идентификатор объекта:
weightarray -> [0,1,2,3]
positionarray -> [0,1,2,3]
velocityarray -> [0,1,2,3]
Этот подход работает хорошо, если все объекты имеют каждый из атрибутов. Однако, если только объекты 0 и 2 имеют все атрибуты дерева, а другие - объекты типа, которые не перемещаются, они не будут иметь скорость, и данные будут выглядеть:
weightarray -> [0,1,2,3]
positionarray -> [0,1,2,3]
velocityarray -> [0,2] //either squash it like this
velocityarray -> [0 ,2 ] //or leave "empty gaps" to keep alignment
Вдруг это не так легко повторить. Компонент, интересующийся только итерацией и манипулирование скоростью, должен был либо как-то пропустить пустые пробелы, если бы пошел вторым путем. Первый подход к поддержанию короткого массива не будет хорошо работать ни в более сложных ситуациях. Скажем, есть ли у меня один объект 0 со всеми тремя атрибутами, другой объект 1, имеющий только вес и положение, и объект 2, который имеет только положение и скорость. Наконец, есть одна последняя сущность 3, которая имеет только вес. Сжатые массивы выглядят так:
weightarray -> [0,1,3]
positionarray -> [0,1,2]
velocityarray -> [0,2]
Другой подход оставил бы такие пробелы:
weightarray -> [0,1, ,3]
positionarray -> [0,1,2, ]
velocityarray -> [0, ,2, ]
Обе эти ситуации нетривиальны для итерации, если вас интересует только итерация по множеству объектов, у которых есть только несколько атрибутов. Например, данный компонент X был бы заинтересован в обработке объектов с положением и скоростью, например. Как я могу извлечь итеративные указатели массива, чтобы дать этому компоненту выполнить его вычисления? Я хотел бы дать ему массив, в котором элементы находятся рядом друг с другом, но это кажется невозможным.
Я думал о таких решениях, как наличие поля бит для каждого массива, описание того, какие пятна являются допустимыми и какие пробелы, или система, которая копирует данные во временные массивы, которые не имеют отверстий, а затем передаются компонентам, и другие идеи, но ни один из них, о котором я думал, был изящным и не имел дополнительных накладных расходов на обработку (например, дополнительные проверки, если данные действительны или дополнительное копирование данных).
Я спрашиваю здесь, потому что я надеюсь, что кто-то из вас может иметь опыт с чем-то похожим или может иметь идеи или мысли, полезные для решения этой проблемы.:) Также, если вся эта идея дерьмовая и невозможная для правильного выбора, и у вас есть гораздо лучшая идея, пожалуйста, скажите мне. Надеюсь, вопрос не слишком длинный или беспорядочный.
Спасибо.