Changements d'état dans les entités ou les composants

9

J'ai du mal à comprendre comment gérer la gestion de l'État dans mes entités.

Je n'ai aucun problème avec la gestion de l'état du jeu, comme la pause et les menus, car ceux-ci ne sont pas traités comme un système de composants d'entité; juste avec l'état dans les entités / composants.

Comme dessin à partir d'Orcs Must Die, j'ai mes entités MainCharacter et Trap qui n'ont que leurs composants comme PositionComponent, RenderComponent, PhysicsComponent.

À chaque mise à jour, l'entité appellera la mise à jour de ses composants. J'ai également un EventManager générique avec des écouteurs pour différents types d'événements.

Maintenant, je dois pouvoir placer les pièges: sélectionnez d'abord le piège et la position du piège, puis placez le piège.

Lorsque vous placez un piège, il doit apparaître devant le personnage principal, rendu d'une manière différente et le suivre. Une fois placé, il devrait simplement répondre aux collisions et être rendu de la manière normale.

Comment cela est-il généralement géré dans les systèmes basés sur des composants?

(Cet exemple est spécifique mais peut aider à comprendre la manière générale de gérer les états des entités.)

GriffinHeart
la source
1
Pouvez-vous ajouter et supprimer des composants d'entités en fonction des événements d'entrée? Vous pouvez peut-être modifier les composants du piège lorsque les états changent. Par exemple, lors du placement du piège, il aura FollowComponent et RenderEffectComponnent. Une fois placé, vous supprimez les deux composants et ajoutez CollisionComponent. (Edit: Plus clairement exprimé par Martin Sojka)
Asakeron
Oui, je peux, chaque entrée est traduite d'un "HumanView" en événements de jeu, qui, la plupart d'entre eux, sont d'abord traités par ma classe GameLogic, qui vérifiera par exemple si le personnage principal a assez d'argent pour placer un piège, comment il arrive après c'est ce que j'essaie de comprendre.
GriffinHeart

Réponses:

6

Une application intéressante d'un système de composants est que vous pouvez modifier les composants d'une entité au moment de l' exécution si vous l'avez conçu pour pouvoir gérer de tels composants . L'état d'une entité devient ainsi la somme des composants qui lui sont attribués et des valeurs qu'ils contiennent.

Pour votre exemple, vous pouvez d'abord créer le piège avec a BuildControllerComponent(régissant la réaction aux contrôles des joueurs en phase de construction), a PositionComponentet a RenderComponent. Le dernier a un champ de données qui régit le pixel shader (s) utilisé, et l'un d'eux donne au piège à construire un aspect "fantomatique". Vous remarquerez qu'aucun composant physique n'a encore été attribué.

En plaçant le piège, les composants sont échangés. Le BuildControllerComponentn'est plus nécessaire, il est donc supprimé. Les RenderComponentshaders sont remplacés par votre vue standard normale du piège. Enfin, PhysicsComponenttout ce qui est nécessaire au fonctionnement du piège est ajouté à l'entité.

Dans une approche basée sur l'héritage, cela équivaut à avoir un constructeur pour une ActiveTrapEntityclasse qui prend une BuildTimeTrapEntityclasse comme arguments, le second étant utilisé pour rendre le piège pendant sa construction, le premier étant utilisé pour le piège après qu'il soit en place .

Martin Sojka
la source
C'est intelligent.
Cypher
1
C'est une bonne stratégie pour appliquer l'état d'une entité. Il n'aborde pas la question de savoir comment suivre l'état de chaque entité. Comment savez-vous dans quel état l'entité se trouve actuellement?
MichaelHouse
@MartinSojka Cela se rapproche de ce que je pensais après avoir posé la question. J'envisageais d'ajouter un BuildTrapProcess (quelque chose qui est mis à jour chez GameLogic) qui gérera l'aspect d'exécution des composants changeants pour obtenir les changements d'état nécessaires pour construire un piège. Lorsque le bouton de construction d'un piège est pressé, la logique du jeu crée le processus et le démarre. des réflexions sur cette approche?
GriffinHeart
@ Byte56: En général, vous pouvez interroger les composants associés et ses valeurs. Dans la pratique, vous n'avez souvent besoin que de connaître le sous-ensemble pertinent de l'état entier, par exemple "Cette entité a- BuildControllerComponentt -elle ?" ou "Quelle est la position de cette entité telle qu’elle est enregistrée dans son PositionComponentcas, le cas échéant?" - ceux que vous faites en vérifiant la liste des composants pour ceux qui vous intéressent et en interrogeant éventuellement (certaines) leurs valeurs.
Martin Sojka
1
@GriffinHeart: Je ne ferais qu'implémenter tout ce qui est nécessaire pour "construire" le piège dans le système associé à la gestion de BuildControllerComponents. Il doit déjà traiter les changements de point de vue du personnage du joueur (ou de la caméra) et les événements de touche et de souris.
Martin Sojka
5

Je n'aime pas l'idée d'entités appelant des mises à jour sur leurs composants (les systèmes devraient faire le travail), et cela va conduire à des problèmes pour garder les composants ignorants les uns des autres.

Vous pouvez ajouter un composant supplémentaire appelé "État". Il sera accessible par vos systèmes de rendu et de collision. Le composant d'état n'est qu'un indicateur qui dispose de plusieurs états. Pour la situation que vous décrivez, les États seraient Playet Build. Lorsque le système de rendu constate que l'état est, Buildil dessine l'objet translucide. Lorsque le système de collision voit l' Buildétat, il ne traite pas les collisions avec le joueur.

Mais vraiment, si vous n'avez pas de système et que vous comptez sur des composants pour faire tout le travail, vous allez rencontrer beaucoup de problèmes. Les composants ne devraient pas se connaître et ne devraient pas faire de traitement.

MichaelHouse
la source
Ce que vous dites est contradictoire, d'abord ils ne devraient pas le savoir (ce que je suis d'accord), puis vous suivez en ayant un composant auquel les autres ont accès. Pouvez-vous clarifier? Je garde les composants découplés par le système d'événements.
GriffinHeart
Je dis les deux. Je dis qu'ils ne devraient pas être au courant et essayer d'adapter ma réponse à la façon dont je pense que vous gérez les composants. Lorsque vous dites «l'entité appellera la mise à jour de ses composants», cela me fait croire que vous n'avez pas d'entités de traitement des systèmes. J'ai supprimé le langage déroutant et je l'ai juste fait dire systèmes. Je disais des composants parce que je comprenais que c'était ainsi que vous mettiez à jour.
MichaelHouse
J'aime l'idée d'un StateComponentqui peut être consommé par plusieurs systèmes.
Cypher
1
Il est poli de motiver les votes négatifs. Merci.
MichaelHouse
2
Sur une note différente, votre objection à l'approche du demandeur repose sur l'hypothèse que toute conception basée sur les composants doit mettre à jour les composants de systèmes distincts (comme une conception de système d'entité). C'est une façon de le faire, mais certainement pas la seule, et il n'y a aucune raison de dissuader une telle approche pour un jeu qui n'a pas besoin de boucles de mise à jour des composants d'optimisation du cache.
Sean Middleditch