В настоящее время я сталкиваюсь со следующей проблемой:
Я пытаюсь написать клон понг с помощью системы компонентов сущности (ECS). Я написал "рамки" все сам. Таким образом, существует класс, который управляет объектами со всеми компонентами. Тогда есть сами классы компонентов. И, наконец, есть мои системы, которые просто получают все объекты, которые имеют компоненты, в которых нуждается система.
Так, например, моя система перемещения ищет все объекты, которые имеют компонент положения и компонент движения. Компонент позиции просто удерживает позицию, а компонент движения - скорость.
Но настоящая проблема - моя система столкновений. Этот класс похож на логический шарик. У меня так много особых случаев в этом классе.
Например: мои весла могут сталкиваться с границами. Если это происходит, их скорость устанавливается на ноль. Мой мяч также может столкнуться с границами. Но в этом случае его скорость просто отражается от нормали границы, поэтому она отражается. Для этого я дал мячу дополнительный физический компонент, который просто говорит: «Эй, эта вещь не останавливается, она отражает». Так что на самом деле физический компонент не имеет реальных данных. Это пустой класс, который просто сообщает системе, отражается ли объект или останавливается.
Затем приходит следующее: я хочу визуализировать некоторые частицы, когда шар сталкивается с веслами или границами. Поэтому я думаю, что шар должен получить еще один компонент, который говорит системе столкновений создавать частицы при столкновении.
Тогда я хочу иметь бонусы, которые могут сталкиваться с веслами, но не с границами. Если это произойдет, бонусы должны исчезнуть. Поэтому мне понадобится гораздо больше кейсов и компонентов (чтобы сообщить системе, что некоторые объекты могут сталкиваться только с определенными, а не со всеми, даже если некоторые действительно могут сталкиваться, более того, система столкновений должна была применять бонусы к весла и тд и тд и тп).
Я вижу, что система компонентов сущности - это хорошо, потому что она гибкая и у вас нет проблем с наследованием. Но я полностью застрял в настоящее время.
Я думаю, что слишком сложно? Как мне справиться с этой проблемой?
Конечно, я должен создать системы, которые на самом деле отвечают за «постколлизию», поэтому система коллизий говорит только «Да, у нас коллизия в последнем кадре», а затем есть куча «постколлизионных» систем, которые все требуют разных (комбинаций) компонентов и затем меняют компоненты. Например, была бы система постколлизионного движения, которая останавливает вещи, которые должны остановиться, когда происходит столкновение. Затем физическая постколлизионная система, которая отражает вещи и т. Д.
Но мне это тоже не кажется правильным решением, потому что, например:
- Моей системе постколлизионного перемещения потребуются объекты, имеющие компонент положения, компонент движения и компонент столкновения. Тогда он установит скорость объекта на ноль.
- Физической системе после столкновения потребуются объекты, которые имеют компонент положения, компонент движения, компонент столкновения и компонент физики. Тогда это будет отражать вектор скорости.
Проблема очевидна: движению после столкновения нужны объекты, которые являются подмножеством объектов в физике системы после столкновения. Таким образом, две системы после столкновения будут работать с одними и теми же данными, в результате чего: хотя у объекта есть физический компонент, его скорость будет равна нулю после столкновения.
Как эти проблемы решаются в целом в системе компонентов объекта? Эти проблемы вообще обычные или я что-то делаю не так? Если да, что и как должно быть сделано вместо этого?
источник
Вы слишком усложняете вещи. Я бы сказал, что даже использование компонентного дизайна для такой простой игры просто излишне. Делайте то, что делает вашу игру быстрой и легкой в разработке. Компоненты помогают с итерацией в больших проектах с огромным разнообразием поведений и конфигураций игровых объектов, но их польза от такой простой, четко определенной игры более сомнительна. В прошлом году я говорил об этом: вы можете создавать забавные маленькие игры за несколько часов, если сосредоточитесь на создании игры вместо того, чтобы придерживаться архитектуры . Наследование нарушается, когда у вас есть 100 или даже 20 различных типов объектов, но оно прекрасно работает, если у вас есть только несколько таких объектов.
Предполагая, что вы хотите продолжать использовать компоненты в учебных целях, есть некоторые очевидные проблемы с вашим подходом, которые выделяются.
Во-первых, не делайте ваши компоненты такими маленькими. Нет причин иметь мелкозернистые компоненты, такие как «движение». В вашей игре нет общего движения. У вас есть весла, движение которых тесно связано с вводом или ИИ (и на самом деле вы не используете скорость, ускорение, восстановление и т. Д.), И у вас есть мяч, у которого есть четко определенный алгоритм движения. Просто имейте компонент PaddleController и компонент BouncingBall или что-то в этом роде. Если / когда вы получаете более сложную игру, вы можете беспокоиться о наличии более общего компонента PhysicsBody (который в «реальных» движках - это просто связь между игровым объектом и любым внутренним объектом API, используемым Havok / PhysX / Bullet /). Box2D / и т. Д.), Который обрабатывает самые разные ситуации.
Даже компонент «позиция» сомнителен, хотя, конечно, не редкость. Физические движки обычно имеют свое внутреннее представление о том, где находится объект, графика может иметь интерполированное представление, а ИИ может иметь еще одно представление тех же данных в другом состоянии. Может быть полезным просто дать каждой системе возможность управлять собственным представлением о преобразовании в ее собственных компонентах, а затем обеспечить бесперебойную связь между системой. Смотрите сообщение в блоге BitSquid о потоках событий .
Для пользовательских физических движков помните, что вам разрешено иметь данные о ваших компонентах. Возможно, у общего компонента физики понга есть данные, указывающие, по каким осям он может двигаться (скажем,
vec2(0,1)
как множитель для лопастей, которые могут двигаться только по оси Y, иvec2(1,1)
для шара, указывающего, что он может двигаться), флаг или поплавок, указывающий на бодрость ( мяч, как правило, на1.0
и весла на0.0
), характеристики ускорения, скорость и т. д. Попытка разделить это на миллионы различных микрокомпонентов для каждого фрагмента данных с высокой степенью взаимосвязи противоречит тому, что изначально предполагалось сделать ECS. Храните вещи, которые используются вместе, в одном и том же компоненте, где это возможно, и разделяйте их только тогда, когда существует большая разница в том, как каждый игровой объект использует эти данные. Есть аргумент в пользу того, что для Понга физика между мячом и веслами достаточно различна, чтобы быть отдельными компонентами, но для более крупной игры нет особой причины пытаться сделать 20 компонентов, чтобы делать то, что отлично работает в 1-3.Помните, что если / когда ваша версия ECS будет мешать, делайте то, что вам нужно, чтобы реально сделать свою игру, и забудьте о неуклонном следовании шаблону / архитектуре дизайна.
источник
Ball
который содержит всю логику для мяча, как движение, подпрыгивание и т. Д., ИPaddle
компонент, который принимает входные данные, но это я. Все, что имеет для вас наибольшее значение и мешает вам сделать игру, - это «правильный путь».На мой взгляд *), ваша самая большая проблема с компонентами заключается в следующем: компоненты не здесь, чтобы сказать кому-либо еще, что делать. Компоненты здесь, чтобы делать вещи. У вас нет компонента, который бы просто удерживал память о чем-то, а затем заставлял другие компоненты работать с этим. Вам нужны компоненты, которые ДОПУСКАЮТСЯ с данными, которые они получили.
Если вы сами проверяете наличие других компонентов (а затем вызываете функции там), то это явный признак того, что любая из двух вещей верна:
Invalidate()
илиSetDirty()
призывы к другим компонентам.Кстати, это относится ко всем видам систем, не только к системам Entity / Component, но и к классическому наследованию с простыми «GameObject» или даже библиотечными функциями.
*) На самом деле только мой . Мнения сильно различаются по поводу Whats Da Real Component Systemz (TM)
источник