2010-09-14 36 views
10

J'imagine que cette question ou les variations de celle-ci se passent beaucoup, donc si ce que je dis est un doublon, et les réponses se trouvent ailleurs, s'il vous plaît informez-moi. J'ai fait des recherches sur les conceptions de moteurs de jeu et j'ai découvert le modèle d'entité basé sur les composants. Cela semble prometteur, mais je travaille encore sur sa mise en œuvre.Gestion d'événements dans la conception de moteur de jeu basé sur des composants

Je considère un système où le moteur est organisé de plusieurs "sous-systèmes", qui gèrent certains aspects, comme le rendu, le son, la santé, AI, etc. Chaque sous-système a un type de composant associé, comme un composant pour le sous-système de santé. Une "entité", par exemple un PNJ, une porte, un effet visuel ou le joueur, est simplement composée d'un ou de plusieurs composants, qui, une fois réunis, confèrent à l'entité sa fonctionnalité. J'ai identifié quatre canaux principaux de transmission d'information: un composant peut diffuser vers tous les composants de son entité actuelle, un composant peut diffuser vers son sous-système, un sous-système peut diffuser vers ses composants et un sous-système peut diffuser vers d'autres sous-systèmes.

Par exemple, si l'utilisateur souhaitait déplacer ses caractères, il appuyait sur une touche. Cette pression sur la touche serait captée par le sous-système d'entrée, qui diffuserait alors l'événement et serait récupéré par le sous-système du joueur. Le sous-système du joueur envoie alors cet événement à tous les composants du joueur (et donc aux entités composant ces composants), et ces composants du joueur communiquent avec le composant de position de sa propre entité pour aller de l'avant et se déplacer.

Tout cela pour une touche presse semble un peu sinueux, et je suis certainement ouvert à des améliorations à cette architecture. Mais de toute façon, ma question principale suit toujours. En ce qui concerne les événements eux-mêmes, j'ai considéré où un événement se comporte comme dans le modèle de visiteur. L'importance de ce que je veux, c'est que si un événement rencontre un composant qu'il ne supporte pas (comme dans un événement de déplacement n'a rien à voir avec AI ou santé), il ignorerait le composant. Si un événement ne trouve pas le composant recherché, cela n'a pas d'importance.

Le modèle de visiteur fonctionne presque. Cependant, il faudrait que j'aie des fonctions virtuelles pour chaque type de composant (c'est-à-dire visitHealthComponent, visitPositionComponent, etc.) même si cela n'a rien à voir avec eux. Je pourrais laisser ces fonctions vides (donc si elles tombaient sur ces composants, elles seraient ignorées), mais je devrais ajouter une autre fonction chaque fois que j'ajoute un composant. Mes espoirs étaient que je serais capable d'ajouter un composant sans nécessairement ajouter des trucs à d'autres endroits, et ajouter un événement sans jouer avec d'autres choses.

Alors, mes deux questions:

  1. Y at-il des améliorations ma conception pourrait permettre, en termes d'efficacité, de flexibilité, etc.?
  2. Quelle serait la façon optimale de gérer les événements?

Répondre

1

J'ai envisagé d'utiliser des systèmes d'entités pour l'un de mes propres projets et j'ai suivi un processus de réflexion similaire. Mon idée initiale était d'utiliser un pattern Observer pour gérer les événements - Moi aussi, à l'origine, je considérais une sorte de modèle de visiteur, mais j'ai décidé de ne pas le faire pour les raisons que vous avez évoquées. Je pense que les sous-systèmes fourniront une interface de publication/abonnement spécifique au sous-système, et que les dépendances de sous-systèmes seront résolues de manière "semi-lâche".Tout sous-système qui dépend des événements d'un autre sous-système connaîtra l'interface de l'abonné à ce sous-système et pourra ainsi en faire un usage efficace.

Malheureusement, la façon dont ces abonnés reçoivent des identifiants pour leurs éditeurs reste un problème dans mon esprit. À ce stade, je privilégie une sorte de création dynamique où chaque sous-système est instancié, puis une seconde phase est utilisée pour résoudre les dépendances et mettre tous les sous-systèmes dans un «état prêt».

Quoi qu'il en soit, je suis très intéressé par ce qui a fonctionné pour vous et tous les problèmes que vous rencontrez sur votre projet :)

1

Utilisez un bus d'événements, alias aggrégateur de l'événement. Ce que vous voulez, c'est un mécanisme d'événement qui ne nécessite aucun couplage entre les sous-systèmes, et un bus d'événement fera exactement cela.

http://martinfowler.com/eaaDev/EventAggregator.html http://stackoverflow.com/questions/2343980/event-aggregator-implementation-sample-best-practices

etc

1

cette architecture décrite ici http://members.cox.net/jplummer/Writings/Thesis_with_Appendix.pdf Il y a au moins trois problèmes J'ai rencontré la mise en œuvre dans un vrai projet:

  1. Les systèmes ne sont pas notifiés quand quelque chose arrive - la seule façon est de poser des questions à ce sujet - le joueur est mort? le mur n'est pas visible? et ainsi de suite - pour éviter cela, vous pouvez utiliser MVC simple au lieu du modèle d'observateur.
  2. que se passe-t-il si votre objet est composé (c'est-à-dire constitué d'objets)? le système traversera toute la hiérarchie et posera des questions sur l'état du composant.
  3. Et le principal inconvénient est que cette architecture mélange tous ensemble - par exemple, pourquoi le joueur a-t-il besoin de savoir que vous avez appuyé sur une touche?

je pense que la réponse est des architectures en couches avec une représentation abstraite ...

1

Excuse mon mauvais anglais. Je suis en train d'écrire un moteur de jeu java 3d flexible et évolutif basé sur le système Entity-Component. J'ai fini quelques parties de base.

D'abord je veux dire quelque chose sur l'architecture ECS, je ne suis pas d'accord qu'un composant peut communiquer avec d'autres composants dans une même entité. Les composants ne doivent stocker que des données et les systèmes les traitent.

Dans le cadre de la gestion des événements, je pense que la gestion des entrées de base ne doit pas être incluse dans un ECS. Au lieu de cela, j'ai un système appelé système d'intention et j'ai un composant appelé composant d'intention qui contient de nombreuses intentions. Une intention signifie qu'une entité veut faire quelque chose vers une entité. Le système d'intention traite toutes les intentions. Lorsqu'il traite une intention, il transmet les informations correspondantes à d'autres systèmes ou ajoute d'autres composants à l'entité. J'écris également une interface appelée Intent Generator. Dans le jeu local, vous pouvez implémenter une entrée clavier ou un générateur d'entrée souris et dans un jeu multi-joueurs, vous pouvez implémenter un générateur d'intention réseau. Dans le système AI, vous pouvez également générer des intentions.

Vous pensez peut-être que le système Intent traite trop de choses dans le jeu. Mais en fait, il partage beaucoup de traitement avec d'autres systèmes et j'écris aussi un système de script. Pour une entité spéciale spécifique, un composant script fait des choses spéciales.A l'origine, lorsque je développe quelque chose, je veux toujours faire une grande architecture qui comprend tout. Mais pour le développement de jeux, il est parfois très inefficace. Un objet de jeu différent peut avoir des fonctions complètement différentes. ECS est excellent en tant que système de programmation orienté données. mais nous ne pouvons pas tout inclure pour un jeu complet. Par ailleurs, notre moteur de jeu basé sur ECS sera open source dans un avenir proche, alors vous pouvez le lire. Si cela vous intéresse, je vous invite également à nous rejoindre.