Tout d'abord, je ne parle pas de gestion de scène; Je définis librement l'état du jeu comme toute sorte d'état dans un jeu qui a des implications sur l'activation ou non de l'entrée utilisateur, ou si certains acteurs doivent être temporairement désactivés, etc.
À titre d'exemple concret, disons que c'est un jeu du Battlechess classique. Après avoir fait un geste pour prendre la pièce d'un autre joueur, une courte séquence de bataille est jouée. Pendant cette séquence, le joueur ne devrait pas être autorisé à déplacer des pièces. Alors, comment pourriez-vous suivre ce type de transition d'état? Une machine à états finis? Une simple vérification booléenne? Il semble que ce dernier ne fonctionnerait bien que pour un jeu avec très peu de changements d'état de ce type.
Je peux penser à beaucoup de façons simples de gérer cela en utilisant des machines à états finis, mais je peux aussi les voir devenir rapidement incontrôlables. Je suis simplement curieux de savoir s'il existe un moyen plus élégant de suivre les états / transitions du jeu.
Réponses:
Une fois, je suis tombé sur un article qui résout votre problème avec élégance. Il s'agit d'une implémentation FSM de base, appelée dans votre boucle principale. J'ai décrit le résumé de base de l'article dans le reste de cette réponse.
Votre état de jeu de base ressemble à ceci:
Chaque état de jeu est représenté par une implémentation de cette interface. Pour votre exemple Battlechess, cela pourrait signifier ces états:
Les états sont gérés dans votre moteur d'état:
Notez que chaque état a besoin d'un pointeur vers le CGameEngine à un moment donné, afin que l'état lui-même puisse décider si un nouvel état doit être entré. L'article suggère de passer le CGameEngine en tant que paramètre pour HandleEvents, Update et Draw.
Au final, votre boucle principale ne traite que du moteur d'état:
la source
Je commence par gérer ce genre de chose de la manière la plus simple possible.
Ensuite, j'ajouterai les contrôles par rapport à ce drapeau booléen aux endroits appropriés.
Si je découvre par la suite que j'ai besoin de plus de cas particuliers que cela - et seulement cela - je me réintègre dans quelque chose de mieux. Il y a généralement 3 approches que je prendrai:
enum { PRE_MOVE, MOVE, POST_MOVE }
et ajoutez les transitions là où vous en avez besoin. Ensuite, je peux vérifier cette énumération où je vérifiais le drapeau booléen. Il s'agit d'un changement simple, mais qui réduit le nombre d'éléments à vérifier, vous permet d'utiliser des instructions switch pour gérer efficacement le comportement, etc.pieceSelectionManager->disable()
ou similaire au début de la séquence, etpieceSelectionManager->enable()
. Vous avez toujours essentiellement des drapeaux, mais maintenant ils sont stockés plus près de l'objet qu'ils contrôlent, et vous n'avez plus besoin de conserver d'état supplémentaire dans votre code de jeu.D'une manière générale, je n'ai jamais besoin d'aller plus loin en ce qui concerne les sous-états de cas spéciaux, donc je ne pense pas qu'il y ait un risque de «perdre rapidement le contrôle».
la source
http://www.ai-junkie.com/architecture/state_driven/tut_state1.html est un joli tutoriel pour la gestion de l'état du jeu! Vous pouvez l'utiliser soit pour des entités de jeu, soit pour un système de menus comme ci-dessus.
Il commence à enseigner le modèle de conception d'état , puis continue à implémenter un
State Machine
, et l'étend successivement de plus en plus. C'est une très bonne lecture! Vous donnera une solide compréhension du fonctionnement de l'ensemble du concept et de son application à de nouveaux types de problèmes!la source
J'essaie de ne pas utiliser la machine d'état et les booléens à cet effet, car les deux ne sont pas évolutifs. Les deux se transforment en désordre lorsque le nombre d'États augmente.
Je conçois généralement le gameplay comme une séquence d'actions et de conséquences, tout état de jeu vient naturellement sans qu'il soit nécessaire de le définir séparément.
Par exemple, dans votre cas avec la désactivation de l'entrée du lecteur: vous avez un gestionnaire d'entrée utilisateur et une indication visuelle dans le jeu que l'entrée est désactivée, vous devez en faire un seul objet ou composant, donc pour désactiver l'entrée, vous désactivez simplement l'objet entier, pas besoin de synchronisez-les dans une machine d'état ou réagissez à un indicateur booléen.
la source