Я написал систему компонентов сущности для моей игры (C ++). Затем я реорганизовал мою систему рендеринга для работы с Entities / RenderComponents, а не с каким-то виртуальным интерфейсом для рисования. Это некоторые классы, для которых я не думаю, что имеет слишком много смысла, чтобы заставить их быть компонентом. Одним из таких классов является карта.
Мой класс карты состоит из класса плиточной местности и некоторых других данных (не важно). Класс плиточной местности управляет несколькими слоями в форме (что на данный момент) TiledTerrainLayer
учебный класс. Перед рефакторингом системы рендеринга я просто унаследовал от Drawable
а также Transformable
чтобы этот класс отображался системой рендеринга. Теперь необходимо быть субъектом с по крайней мере TransformComponent
и немного RenderComponent
,
Теперь TiledTerrainLayerRenderComponent
должен действительно иметь только вершины и ссылку на текстуру и, возможно, флаг того, была ли она уже создана. TiledTerrainComponent
будет принадлежать список индексов плитки, а также размер плитки и карты.
Теперь моя проблема в том, что когда я устанавливаю плитку (используя что-то вроде SetTile(size_t tileIndex, const Position & pos)
Метод, я также должен обновить текстурные координаты массива вершин.
Я обычно в порядке с одним компонентом, требующим другого компонента. Например, SpriteRenderComponent
требует TransformComponent
и я также в порядке с одним компонентом доступа к информации другого. Например. метод GetBoundingBox () использует положение компонента преобразования.
Чего я хочу избежать, так это того, что два компонента «перекрестно ссылаются» друг на друга, как это было бы в случае с TiledTerrainComponent
(TTC) и TiledTerrainRenderComponent
, (TTRC) (TTRC получает tileIndexList TTC для создания себя, и TTC вызывает метод UpdateVertices () TTRC, когда вызывается его метод SetTile ().
Наконец, я знаю, что компоненты должны быть в основном данными. Я только добавил методы, которые напрямую получают или изменяют эти данные, такие как SetTile () или GetTexture (). Будет ли система жизнеспособной в случае, описанном выше, и если да, как она будет выглядеть?
Похоже, все, что вам нужно здесь, это Грязный флаг.
Когда вы изменяете индекс, размер или другие свойства тайла на своем Tiled Terrain, вы не сразу звоните в Tiled Renderer, чтобы обновить его вершины (в конце концов, у вас может быть много обновлений плиток, которые еще не появились в этом фрейме — это может быть расточительно пересчитать твои вершины каждый раз)
Вместо этого рендерер Tiled Terrain просто устанавливает свой внутренний hasBeenModifiedSinceLastUse
признак истины. Ему вообще не нужно знать о рендерере.
Затем, когда вы обновляете свой Tiled Renderer непосредственно перед рисованием, вы должны спросить его Tiled Terrain, обновлялся ли он с момента последнего рисования (вы даже можете запросить список обновлений, если хотите нацелить изменения). Если это так, вы обновляете вершины в одном большом пакете для лучшего кода & местонахождение данных.
При этом вы сбрасываете измененный флаг, чтобы в случае отсутствия обновлений в последующих кадрах вы могли повторно использовать последний сгенерированный набор вершин как есть.
Теперь ваша зависимость указывает только на один путь — рендеринг зависит от данных мозаики, но данные мозаики не знают о рендеринге, кроме поддержания своего флага.
Других решений пока нет …