Ідентифікація "типів" сутності в системі суб'єктів-компонентів


10

Якщо суб'єкт господарювання не має явного "типу" (наприклад, програвач) і є просто колекцією компонентів, то як я можу визначити об'єкти, над якими мої системи повинні і не повинні працювати? Наприклад, в грі в понг весло і м'яч стикаються з межами вікна. Однак системи керування зіткненнями для кожної з них будуть різними, тому система не повинна обробляти об'єкти неправильного типу.

void PlayerCollisionSystem::update(std::vector<Entity *> entities) {
  typedef std::vector<Entity *>::iterator EIter;
  for (EIter i = entities.begin(); i != entities.end(); ++i) {
    Entity *player = *i; // How do I verify that the entity is a player?

    // Get relevant components.
    PositionComponent *position = player->getComponent<PositionComponent>();
    VelocityComponent *velocity = player->getComponent<VelocityComponent>();
    SpriteComponent *sprite = player->getComponent<SpriteComponent>();

    // Detect and handle player collisions using the components.
  }
}

І гравець, і м'яч мають однакові відповідні типи компонентів для керування зіткненнями, але їх реалізація системи буде різною.

Якщо у мене є контейнер з усіма ігровими об'єктами, як я можу ідентифікувати конкретні типи сутності, не успадковуючи Entityта не включаючи змінну члена, наприклад std::string type, у такому випадку суб'єкт господарювання вже не є просто колекцією компонентів?

Відповіді:


21

Відповідь Ніколя Боласа прямо зараз, але відступаючи і дивлячись на проблему здалеку: вам не потрібен тип сутності.

Вам потрібно дбати лише про те, "об'єкт має компонент X" чи ні, і ваша проблема полягає в тому, що ви неправильно ідентифікували X. Якщо два об'єкти поводяться по-різному, то надайте їм різні компоненти або просто поставте бульний прапор на компонент, якщо він змусить себе поводитися по-різному для різних конфігурацій об'єкта. Використовуйте систему компонентів для прийняття рішень щодо поведінки, а не сутності "типу". У цьому вся суть використання компонентів.

Вам повністю дозволено мати PaddlePhysicsкомпонент / систему та окремий BallPhysicsкомпонент / систему, якщо вони поводяться по-різному. Або ви можете зламати компоненти в більш дрібні деталі , такі , що у вас є Bounceкомпонент , який тільки м'яч і StopAtBoundaryкомпонент , який , як Ballі Paddleє , якщо частина поведінки досить складна , щоб виправдати розділення коду. Або ви можете просто зробити PongPhysicsкомпонент , який має логічний прапор Bouncesнабір trueдля Ballі falseдля Paddle. Ви навіть можете зробити базовий WallCollisionкомпонент, а потім вивести цей компонент, щоб отримати той, BallWallCollisionякий додає необхідної додаткової поведінки.


4
Я думаю, що це має бути прийнятою відповіддю, оскільки немає абсолютно ніяких обмежень або проблем з "ванільним" ECS. Позначення об'єктів можна легко досягти, створивши виділені компоненти, які служать маркерами. Це також може бути просто фіктивним PlayerTypeComponent, який не робить нічого корисного, а лише служить тегом.
tiguchi

19

Система корисна лише тоді, коли вона корисна. Якщо система, де сутність є "просто колекцією компонентів", є менш корисною, ніж система, де суб'єкт здебільшого є "колекцією компонентів", то зробіть це .

Перестаньте намагатися робити "чисті" системи і зосередьтеся на тому, щоб робити хороші , які роблять те, що вам потрібно. Використовуйте компоненти, поки компоненти не стануть для вас корисними. Потім використовуйте щось інше.

Ви вже витратили більше часу на роздуми над цим, ніж це заслуговує.


дуже приємно +1 "Ви вже витратили більше часу на роздуми над цим, ніж це заслуговує"
вс

8
Я не думаю, що це взагалі відповідь. Тема вдосконалення ECS є такою, яка заслуговує на значну увагу, і Гарі (коли він розмістив це в 2013 році), мабуть, не витратив достатньо часу на її роздуми. Поняття, що тема не заслуговує більше часу, передбачає, що системи повинні бути простими або тривіальними і взагалі незаслуговують нашого часу. Я вважаю за краще відповідь Шона Міддлітча, оскільки він насправді намагається відповісти на питання, а не відхиляти його.
Гевін Вільямс

Чудова відповідь. Мені здається, що мені потрібно це час від часу говорити собі. Зосередьтеся на русі вперед.
Домінік Бу-

5

Якщо ви хочете надати об'єктам явний тип, найпростішим способом є визначення змінної типу в класі сутності. Дотримуйтесь лише моделі ЄК, доки це корисно.

В іншому випадку тип мається на увазі через атрибути компонента. Наприклад, компонент фізики матиме атрибут для мобільних проти стаціонарних. Потім система знає, коли стикаються два мобільні телефони (м'яч і весло). Так само ви можете мати атрибути того, як повинна реагувати система зіткнення. Просто зупинити об’єкт чи відбити його? Перегляд атрибутів повинен дати вам уявлення про те, що таке сутність, але це не має значення. Системам не слід знати, що таке тип сутності, з якою вони працюють, їм слід надати достатньо інформації, використовуючи надані їм компоненти.

Нарешті, ви можете додати додатковий компонент, який містить тип, але, як і при додаванні типу до сутності, ви в кінцевому підсумку будете писати багато специфічного коду, перемагаючи призначення системи EC.


0

Суб'єкт - це сукупність компонентів. Ви не можете призначити акуратні мітки випадковому набору. Надання обмежень типу - ціна за велику гнучкість.

Звичайно, ви можете мати спеціальні (набрані) класи сутностей, які накладають обмеження на компоненти.

В ідеалі компоненти незалежні. Тож вирішенням вашої проблеми було б викликати поводження зіткненнями для кожного підкомпонента по порядку. У реальних додатках є взаємозалежності та проблеми з замовленням. Якщо це так, вам потрібна певна логіка «диспетчера» у кожному методі класу Entity.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.