Depois de analisar alguns padrões de design de jogos, decidi com o Sistema de componentes de entidades (ES System) para o meu mecanismo de jogo. Eu li artigos (principalmente T = Machine ) e revi alguns códigos-fonte e acho que consegui o suficiente para começar.
Há apenas uma idéia básica com a qual estou lutando. Como faço para lidar com grupos de entidades que dependem um do outro?
Deixe-me usar um exemplo:
Suponha que eu estou criando um jogo de tiro aéreo padrão (pense em Jamestown ) e quero construir uma "entidade chefe" com várias partes distintas, mas conectadas. A quebra pode ser algo como isto:
- Corpo do navio: Movimento, Renderização
- Canhão: Posição (bloqueado em relação ao corpo do navio), Rastreamento \ Fogo no herói, Recebendo dano até desativado
- Núcleo: Posição (bloqueado em relação ao corpo do navio), Rastreando \ Fogo no herói, Recebendo dano até desativado, Desativando (er ... destruindo) todas as outras entidades do grupo de navios
Meu objetivo seria algo que seria identificado (e manipulado) como um elemento distinto do jogo sem ter que reescrever o subsistema do zero toda vez que eu quiser criar um novo elemento agregado.
Como implemento esse tipo de design no sistema ES?
- Eu implemento algum tipo de relacionamento de entidade pai-filho (as entidades podem ter filhos)? Isso parece contradizer a metodologia de que as Entidades são apenas contêineres vazios e fazem com que pareça mais POO.
- Eu os implemento como entidades separadas, com algum tipo de componente de conexão (BossComponent) e sistema relacionado (BossSubSystem)? Não posso deixar de pensar que isso será difícil de implementar, uma vez que a forma como os componentes se comunicam parece ser uma grande armadilha.
- Eu os implemento como uma Entidade, com uma coleção de componentes (ShipComponent, CannonComponents, CoreComponent)? Esse parece desviar a intenção do sistema ES (os componentes aqui parecem muito com entidades pesadas), mas eu sei disso, então imaginei que eu colocaria isso lá fora.
- Eu os implemento como outra coisa que mencionei?
Eu sei que isso pode ser implementado com muita facilidade no OOP, mas a minha escolha de ES em vez de OOP é uma que eu vou manter. Se eu precisar romper com a pura teoria da ES para implementar esse design, eu o farei (não como se eu não tivesse comprometido o design puro antes), mas eu preferiria fazer isso por razões de desempenho, em vez de começar com um design ruim.
Para obter crédito extra, pense no mesmo design, mas cada uma das "entidades-chefes" estava realmente conectada a uma "entidade BigBoss" maior, composta por um corpo principal, núcleo principal e três "entidades-chefes". Isso me deixaria ver uma solução para pelo menos três dimensões (avô-pai-filho) ... que deveria ser mais do que suficiente para mim.
fonte
Respostas:
Se eu estivesse nessa situação, criaria cada parte do chefe como uma entidade separada. Estes "sub-entidades" incluiria algum tipo de
AttachmentPoint
ouParentEntity
componente. Esse componente incluiria uma referência à entidade controladora e um deslocamento da posição dos controladores. Ao atualizar a posição, eles verificam a posição pai e aplicam o deslocamento para gerar sua própria posição. Além disso, ele poderia fazer verificações para garantir que a entidade pai ainda exista. Além disso, você pode ter umSubEntity
componente que rastreia a existência de subentidades para a entidade pai. Isso permite que você faça coisas como apenas tornar o núcleo do chefe vulnerável quando os braços com escudos são destruídos.Atualmente, uso um
TargetEntity
componente no meu jogo, que é usado para o rastreamento de torres e quando os goblins vão pegar um recurso. Ele pode verificar a posição da entidade-alvo e alterar seu comportamento de acordo. As entidades que não têm posição nunca são adicionadas como destino, portanto, não há preocupações lá. No entanto, ao aprofundar-se, como verificar a saúde, o escudo, as reservas de energia ou o que quer que seja a entidade pai ou filho, você precisará garantir que a entidade pai ou filho realmente tenha o componente relacionado.Tornar cada parte sua própria entidade mantém a flexibilidade da estrutura da entidade / componente, permitindo adicionar componentes adicionais e diferentes a cada parte do chefe. Por exemplo, uma parte do chefe pode ter um componente de arma e um componente de saúde, enquanto outra teria um componente de escudo e um componente de saúde.
Encontrei outra discussão sobre esse tópico aqui . Na qual os usuários estão discutindo a adição de vários componentes do mesmo tipo a uma entidade (o que me parece uma péssima idéia). Parece uma conversa útil, embora eu não tenha lido toda a discussão.
fonte
Sem conhecer muitos detalhes sobre seus sistemas existentes, a maneira como eu modelaria isso (e, em certa medida, no meu próprio sistema de entidades) é ter um componente como AttachedTo (parentEntity). Qualquer um dos filhos pode receber o componente AttachedTo (chefe).
O sistema de renderização (ou qualquer outra coisa) pega entidades com componentes: Position, AttachedTo, etc. e forma as hierarquias apropriadas.
fonte
Se você deseja ter uma entidade representada por apenas um ID, a contenção de entidades pode ser feita por meio de um componente especial. Você pode chamá-lo CompositeComponent, e isso contém uma lista de IDs de entidades filhas e interfaces para adicionar / remover filhos dessa lista.
Obviamente, todos os componentes que dependem da posição, etc, precisarão trabalhar com este para colocar a entidade adequadamente. Como implementar isso dependerá um pouco de como você implementa o posicionamento atualmente.
A propósito, não existe uma "teoria ES pura" - tornar as entidades fora dos componentes é uma abordagem popular, mas o método preciso ainda não é padronizado.
fonte