Alterações de estado em entidades ou componentes

9

Estou tendo problemas para descobrir como lidar com o gerenciamento de estado em minhas entidades.

Não tenho problemas com o gerenciamento do estado do jogo, como pausa e menus, pois eles não são tratados como um sistema de componentes da entidade; apenas com estado em entidades / componentes.

Desenhando a partir de Orcs Must Die como exemplo, eu tenho minhas entidades MainCharacter e Trap que só têm seus componentes como PositionComponent, RenderComponent, PhysicsComponent.

Em cada atualização, a Entidade chamará atualização em seus componentes. Eu também tenho um EventManager genérico com ouvintes para diferentes tipos de eventos.

Agora eu preciso ser capaz de colocar as armadilhas: primeiro selecione a armadilha e a posição da armadilha e depois coloque a armadilha.

Ao colocar uma armadilha, ela deve aparecer na frente do MainCharacter, renderizada de uma maneira diferente e seguindo-a. Quando colocado, deve apenas responder a colisões e ser processado da maneira normal.

Como isso geralmente é tratado em sistemas baseados em componentes?

(Este exemplo é específico, mas pode ajudar a descobrir a maneira geral de lidar com os estados das entidades.)

GriffinHeart
fonte
11
Você pode adicionar e remover componentes de entidades com base em eventos de entrada? Talvez você possa alterar os componentes da armadilha quando os estados mudarem. Por exemplo, ao colocar a armadilha, ele terá FollowComponent e RenderEffectComponnent. Quando é colocado, você remove os dois componentes e adiciona CollisionComponent. (Edit: Mais claramente expresso por Martin Sojka)
Asakeron
Sim, eu posso, todas as entradas são traduzidas de um "HumanView" para eventos do jogo, que, na maioria, são processados ​​pela minha classe GameLogic, que verificará, por exemplo, se o MainCharacter tem dinheiro suficiente para colocar uma armadilha, como acontece depois disso é o que estou tentando entender.
GriffinHeart 25/10/12

Respostas:

6

Uma aplicação interessante de um sistema de componentes é que você pode alterar os componentes de uma entidade em tempo de execução, se você a projetou para poder lidar com isso. O estado de uma entidade torna-se assim a soma de quais componentes são atribuídos a ela e quais valores os mantêm.

No seu exemplo, você pode primeiro criar a armadilha com a BuildControllerComponent(governando a reação aos controles do jogador na fase de construção), a PositionComponente a RenderComponent. O último possui um campo de dados que governa o sombreador (es) de pixel usado (s), e um deles dá à armadilha a ser construída uma aparência "fantasmagórica". Você notará que ainda não existem componentes físicos atribuídos.

Ao colocar a armadilha, os componentes são trocados. O BuildControllerComponentnão é mais necessário, por isso é removido. Os RenderComponentshaders do são substituídos pela sua visão padrão normal da armadilha. Finalmente, PhysicsComponentassim como tudo o mais necessário para que a armadilha funcione, são adicionados à entidade.

Em uma abordagem baseada em herança, isso equivale a ter um construtor para uma ActiveTrapEntityclasse que usa uma BuildTimeTrapEntityclasse como argumento, o segundo sendo usado para renderizar a armadilha durante a construção e o primeiro sendo usado para a armadilha depois de implementada. .

Martin Sojka
fonte
Isso é inteligente.
Cypher
11
Essa é uma boa estratégia para aplicar o estado de uma entidade. Não trata da questão de como rastrear o estado de cada entidade. Como você sabe em que estado a entidade está atualmente?
MichaelHouse
@MartinSojka Isso chega perto do que eu estava pensando depois de fazer a pergunta. Eu estava pensando em adicionar um BuildTrapProcess (algo que é atualizado no GameLogic) que gerenciará o aspecto do tempo de execução da alteração de componentes para obter as alterações de estado necessárias para criar uma armadilha. Quando o botão para construir uma armadilha é pressionado, a lógica do jogo cria o Processo e o inicia. alguma opinião sobre essa abordagem?
GriffinHeart 25/10/12
@ Byte56: Em geral, você pode consultar os componentes associados e seus valores. Na prática, você geralmente precisa conhecer apenas o subconjunto relevante de todo o estado, por exemplo "Esta entidade possui BuildControllerComponent?" ou "Qual é a posição desta entidade como registrada em sua PositionComponent, se houver alguma?" - aqueles que você faz, verificando a lista de componentes para aqueles em que você está interessado e, opcionalmente, consultando (alguns) seus valores.
Martin Sojka
11
@GriffinHeart: Eu apenas implementaria o que for necessário para "construir" a armadilha no sistema associado ao gerenciamento de BuildControllerComponents. Ele já precisa processar as alterações do ponto de vista do personagem do jogador (ou da câmera) e os eventos de pressionamento de tecla e mouse.
Martin Sojka
5

Não gosto da ideia de entidades chamando atualizações em seus componentes (os sistemas devem estar fazendo o trabalho), e isso levará a problemas em manter os componentes inconscientes um do outro.

Você pode adicionar um componente adicional chamado "Estado". Ele será acessado pelos seus sistemas de renderização e colisão. O componente state é apenas um sinalizador que possui vários estados disponíveis. Para a situação que você descreve, os estados seriam PlayeBuild . Quando o sistema de renderização vê que o estado é, Buildele desenha o objeto translúcido. Quando o sistema de colisão vê oBuild estado, ele não processa colisões com o jogador.

Mas, na verdade, se você não possui sistemas e depende de componentes para fazer todo o trabalho, terá muitos problemas. Os componentes não devem saber um do outro e não devem estar processando.

MichaelHouse
fonte
O que você está dizendo é conflitante, primeiro eles não devem saber (o que eu concordo) e depois você segue com um componente que é acessado por outras pessoas. Você pode esclarecer? Estou mantendo os componentes dissociados pelo sistema de eventos.
GriffinHeart 25/10/12
Estou dizendo os dois. Estou dizendo que eles não devem saber e estão tentando adaptar minha resposta à maneira como acho que você está lidando com componentes. Quando você diz "A entidade chamará a atualização em seus componentes", me faz acreditar que você não possui entidades de processamento de sistemas. Eu removi a linguagem confusa e apenas a fiz dizer sistemas. Eu estava dizendo componentes porque entendia que era assim que você estava atualizando.
MichaelHouse
Eu gosto da idéia de um StateComponentque pode ser consumido por vários sistemas.
Cypher
11
É educado fornecer raciocínio para votos negativos. Obrigado.
MichaelHouse
2
Em uma observação diferente, sua objeção à abordagem do solicitante é baseada na suposição de que todo o design baseado em componentes deve atualizar componentes de sistemas separados (como um design de sistema de entidade). Essa é uma maneira de fazer isso, mas certamente não é a única, e não há razão para dissuadir essa abordagem para um jogo que não precisa de loops de atualização de componentes para otimização de cache.
Sean Middleditch