Изменения состояния в объектах или компонентах

9

У меня возникли проблемы с выяснением того, как поступать с государственным управлением в моих организациях.

У меня нет проблем с управлением игровым состоянием, таким как пауза и меню, поскольку они не обрабатываются как система компонентов объекта; просто с состоянием в сущностях / компонентах.

Рисуя от Orcs Must Die в качестве примера, у меня есть сущности MainCharacter и Trap, в которых есть только такие компоненты, как PositionComponent, RenderComponent, PhysicsComponent.

При каждом обновлении Сущность будет вызывать обновление своих компонентов. У меня также есть универсальный EventManager со слушателями для разных типов событий.

Теперь мне нужно уметь расставлять ловушки: сначала выберите ловушку и положение ловушки, затем разместите ловушку.

При размещении ловушки она должна появляться перед MainCharacter, отображаться по-другому и следовать за ней. Когда помещено это должно только ответить на столкновения и быть предоставленным нормальным способом.

Как это обычно обрабатывается в компонентных системах?

(Этот пример специфичен, но может помочь выяснить общий способ работы с состояниями сущностей.)

GriffinHeart
источник
1
Можете ли вы добавлять и удалять компоненты сущностей на основе входных событий? Возможно, вы сможете изменить компоненты ловушки при изменении состояния. Например, при размещении ловушки у нее будут FollowComponent и RenderEffectComponnent. Когда он размещается, вы удаляете оба компонента и добавляете CollisionComponent. (Правка: более четко выражено Мартином Сойкой)
Асакерон
Да, я могу, каждый вход переводится из «HumanView» в игровые события, которые, большинство из них, сначала обрабатываются моим классом GameLogic, который, например, проверит, достаточно ли у MainCharacter денег для размещения ловушки, как он происходит после того, что я пытаюсь понять.
GriffinHeart

Ответы:

6

Одним интересным применением системы компонентов является то, что вы можете изменять компоненты сущности во время выполнения, если вы спроектировали так, чтобы они могли обрабатывать такие компоненты . Таким образом, состояние объекта становится суммой как того, какие компоненты ему присвоены, так и того, какие значения они содержат.

Для вашего примера, вы можете сначала создать ловушку с BuildControllerComponent(управление реакцией на элементы управления игрока в фазе сборки), a PositionComponentи a RenderComponent. Последнее имеет одно поле данных, которое управляет используемыми пиксельными шейдерами, и одно из них дает «призрачному» виду «ловушку для постройки». Вы заметите, что нет физика компонентов присвоенных еще.

После размещения ловушки компоненты заменяются. Он BuildControllerComponentбольше не нужен, поэтому его удаляют. В RenderComponentшейдеры добудет заменена на нормальном стандартном виде ловушки. Наконец, PhysicsComponentвсе, что нужно для работы ловушки, добавляется к сущности.

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

Мартин Сойка
источник
Это умно.
Cypher
1
Это хорошая стратегия для применения состояния сущности. Здесь не рассматривается вопрос о том, как отслеживать состояние каждого объекта. Как вы узнаете, в каком состоянии находится объект?
MichaelHouse
@MartinSojka Это примерно то, о чем я думал после того, как задал вопрос. Я рассматривал возможность добавления BuildTrapProcess (что-то, что обновлено в GameLogic), который будет управлять аспектом изменения компонентов во время выполнения для достижения изменений состояния, необходимых для создания ловушки. Когда кнопка для построения ловушки нажата, логика игры создаст Процесс и запустит его. есть мысли по поводу этого подхода?
GriffinHeart
@ Byte56: В общем, вы можете запрашивать связанные компоненты и их значения. На практике вам часто нужно знать только соответствующее подмножество всего состояния, например "Имеет ли эта сущность BuildControllerComponent?" или "Какова позиция этой сущности, как записано в ней PositionComponent, если она есть?" - те, которые вы делаете, проверяя список компонентов для тех, кто вас интересует, и опционально запрашивая (некоторые) их значения.
Мартин Сойка
1
@GriffinHeart: я бы просто реализовал все, что нужно для «построения» ловушки в системе, связанной с управлением BuildControllerComponents. Он уже должен обрабатывать изменения точки зрения персонажа (или камеры) игрока и события нажатия клавиш и мыши.
Мартин Сойка
5

Мне не нравится идея, что сущности вызывают обновления своих компонентов (системы должны выполнять эту работу), и это может привести к проблемам, когда компоненты не будут знать друг о друге.

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

Но на самом деле, если у вас нет систем и вы полагаетесь на компоненты для выполнения всей работы, вы столкнетесь с множеством проблем. Компоненты не должны знать друг о друге и не должны выполнять обработку.

MichaelHouse
источник
То, что вы говорите, противоречиво, сначала они должны не знать (что я согласен), а затем вы должны иметь компонент, к которому обращаются другие. Вы можете уточнить? Я держу компоненты отделенными системой событий.
GriffinHeart
Я говорю оба. Я говорю, что они не должны знать, и пытаюсь адаптировать мой ответ к тому, как я думаю, вы работаете с компонентами. Когда вы говорите «Entity будет вызывать update для своих компонентов», это заставляет меня поверить, что у вас нет систем, обрабатывающих сущности. Я удалил запутанный язык и просто заставил его сказать системы. Я говорил компоненты, потому что я понимал, что именно так вы обновляете.
MichaelHouse
Мне нравится идея, StateComponentкоторая может быть использована несколькими системами.
Cypher
1
Вежливо приводить аргументы в пользу отрицательных голосов. Спасибо.
MichaelHouse
2
С другой стороны, ваше возражение против подхода asker основано на предположении, что весь проект на основе компонентов должен обновлять компоненты из отдельных систем (например, проектирование системы сущностей). Это один из способов сделать это, но, конечно, не единственный, и нет никаких причин отрицать такой подход к игре, в которой нет необходимости в циклах обновления компонентов, оптимизирующих кэш.
Шон Мидлдич