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.)
fonte
Respostas:
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), aPositionComponent
e aRenderComponent
. 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
BuildControllerComponent
não é mais necessário, por isso é removido. OsRenderComponent
shaders do são substituídos pela sua visão padrão normal da armadilha. Finalmente,PhysicsComponent
assim 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
ActiveTrapEntity
classe que usa umaBuildTimeTrapEntity
classe 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. .fonte
BuildControllerComponent
?" ou "Qual é a posição desta entidade como registrada em suaPositionComponent
, 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.BuildControllerComponent
s. 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.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
Play
eBuild
. Quando o sistema de renderização vê que o estado é,Build
ele 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.
fonte
StateComponent
que pode ser consumido por vários sistemas.