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


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


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.


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