Identificando 'tipos de entidade' em um sistema de componente de entidade


10

Se uma Entidade não possui um 'tipo' explícito (por exemplo, player) e é simplesmente uma coleção de componentes, como identifico as entidades nas quais meus sistemas devem ou não estar trabalhando? Por exemplo, em um jogo de Pong, a raquete e a bola colidem com os limites da janela. No entanto, os sistemas de tratamento de colisões para cada um serão diferentes, portanto, um sistema não deve manipular entidades do tipo errado.

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.
  }
}

Tanto o jogador quanto a bola compartilham os mesmos tipos de componentes relevantes para o manuseio de colisões, mas as implementações do sistema serão diferentes.

Se eu tenho um contêiner de todas as entidades do jogo, como identifico tipos específicos de entidade sem herdar Entityou incluir uma variável membro, como std::string type, nesse caso, uma entidade não é mais apenas uma coleção de componentes?

Respostas:


21

A resposta de Nicol Bolas é direta, mas se afasta e olha para o seu problema à distância: você realmente não precisa do tipo de entidade.

Você só precisa se preocupar se "o objeto tem componente X" ou não e seu problema é que você não foi identificado corretamente X. Se dois objetos se comportarem de maneira diferente, forneça a eles componentes diferentes ou apenas coloque um sinalizador booleano no componente para que ele se comporte de maneira diferente para configurações de objetos diferentes. Use o sistema de componentes para tomar decisões sobre comportamento, não o tipo de entidade. Esse é o objetivo de usar componentes.

Você está completamente autorizado a ter um PaddlePhysicscomponente / sistema e um BallPhysicscomponente / sistema separado se eles se comportarem de maneira diferente. Ou você pode dividir os componentes em partes mais granulares, de modo que você tenha um Bouncecomponente que apenas o Ball tenha e um StopAtBoundarycomponente que possua ambos Balle Paddlese parte do comportamento for suficientemente complicada para justificar o compartilhamento do código. Ou você pode apenas criar um PongPhysicscomponente que tenha um sinalizador booleano Bouncesdefinido truepara Balle falsepara o Paddle. Você pode até criar um WallCollisioncomponente base e depois derivá-lo para obter um BallWallCollisionque adicione o comportamento extra necessário lá.


4
Eu acho que essa deve ser a resposta aceita, já que não há absolutamente nenhum constrangimento ou problema com o ECS "vanilla". As entidades de marcação podem ser facilmente realizadas criando componentes dedicados que servem como marcadores. Também poderia ser apenas um PlayerTypeComponent fictício que não faz nada de útil, mas serve apenas como tag.
tiguchi 22/02

19

Um sistema é útil apenas se for útil. Se um sistema em que uma entidade é "simplesmente uma coleção de componentes" é menos útil que um sistema em que uma entidade é principalmente uma "coleção de componentes", faça isso .

Pare de tentar criar sistemas "puros" e concentre-se em criar bons que façam o que você precisa. Use componentes até que eles não sejam mais úteis para você. Então use outra coisa.

Você já passou mais tempo pensando sobre isso do que merece.


muito bom +1 "Você já passou mais tempo pensando sobre isso do que merece"
wes

8
Eu não acho que isso seja uma resposta, o tópico de refinar um ECS é aquele que merece atenção significativa, e Garee (quando ele publicou isso em 2013) provavelmente não gastou tempo suficiente pensando nisso. A noção de que o tópico não merece mais tempo implica que os sistemas devem ser simples ou triviais e geralmente não merecem nosso tempo. Eu preferiria a resposta de Sean Middleditch, na verdade ela tenta responder à pergunta em vez de descartá-la.
Gavin Williams

Ótima resposta. Eu me vejo tendo que dizer isso para mim ocasionalmente. Concentre-se em seguir em frente.
Dominic Bou-Samra

5

Se você deseja atribuir às entidades um tipo explícito, a maneira mais fácil é definir uma variável de tipo na classe de entidade. Mantenha o padrão CE apenas enquanto for útil.

Caso contrário, o tipo está implícito nos atributos do componente. Por exemplo, o componente físico teria um atributo para móvel versus estacionário. O sistema então sabe quando dois celulares colidem (bola e raquete). Da mesma forma, você pode ter atributos de como o sistema de colisão deve responder. Basta parar o objeto ou refleti-lo? Examinar os atributos deve fornecer uma idéia do que é a entidade, mas deve ser irrelevante. Os sistemas não precisam saber com que tipo de entidade estão trabalhando, devem receber informações suficientes usando os componentes fornecidos a eles.

Por fim, você pode adicionar um componente adicional que contém um tipo, mas, como a adição de um tipo à entidade, você acabará escrevendo muitos códigos específicos, derrotando o objetivo do sistema EC.


0

Uma entidade é um conjunto de componentes. Você não pode atribuir rótulos elegantes a um conjunto aleatório. Desistir de restrições de tipo é o preço da grande flexibilidade.

É claro que você pode ter classes de entidade especiais (digitadas) que impõem restrições aos componentes.

Idealmente, os componentes são independentes. Portanto, a solução para o seu problema seria chamar o tratamento de colisão em cada subcomponente, em ordem. Em aplicações reais, existem interdependências e problemas de pedidos. Se for esse o caso, você precisa de alguma lógica de 'dispatcher' em todos os métodos da classe Entity.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.