Fondamentalement, dans chaque jeu que j'ai fait jusqu'à présent, j'ai toujours une variable comme "current_state", qui peut être "jeu", "titres d'écran", "gameoverscreen", etc.
Et puis sur ma fonction de mise à jour, j'ai un énorme:
if current_state == "game"
game stuf
...
else if current_state == "titlescreen"
...
Cependant, je ne pense pas que ce soit une manière professionnelle / propre de gérer les états. Avez-vous des idées sur la meilleure façon de procéder? Ou est-ce la voie standard?
lua
architecture
love2d
David Gomes
la source
la source
Réponses:
Puisque vous parlez d'écrans, je pense qu'il est préférable de séparer toute cette logique en différents écrans. Ce que je fais normalement:
Définissez une interface appelée écran et implémentez plusieurs écrans. Comme LoadingScreen, MainMenuScreen, GameScreen, GameOverScreen, HighScoreScreen etc. Dans votre jeu, vous mettez une variable qui contient l'écran actuel. Chaque boucle, vous appelez screen.update () et restituez l'écran actuel. Cela vous fera économiser beaucoup de "si cet état le fait" car votre état est défini par l'écran actuel.
Cela séparera très bien votre logique.
Exemple de code:
Ou selon la configuration de votre jeu, vous avez peut-être une boucle infinie comme jeu.
la source
Si vous utilisez déjà Middleclass, il existe une excellente bibliothèque de machines d'état pour l'accompagner appelée Statefull . Il est facile à utiliser et présente les mêmes idées que Matsemann a proposées.
la source
Si votre
current_state
variable est une chaîne, alors c'est vraiment facile dans Lua:la source
Ce que je fais est à peu près comme suit:
J'ai une structure de données de graphique acyclique dirigée , qui est essentiellement juste un tas de nœuds qui pointent les uns vers les autres. Chaque nœud représente un système de jeu. par exemple l'interface utilisateur, le monde, l'entrée, le rendu. Et chaque nœud pointe vers d'autres nœuds qui le précèdent ou le suivent. Une fois que tous les nœuds sont en place, il est facile de les aplatir en une simple liste. La configuration de ce DAG est la première chose que je fais pendant le démarrage du jeu. Chaque fois que je veux ajouter un nouveau système, disons l'IA, je peux simplement dire écrire ce code puis dire à mon jeu de quoi il dépend et ce qui devrait en dépendre.
Ma boucle de jeu principale vient après cela et exécute simplement chaque système dans l'ordre. La première entrée est gérée, puis les mises à jour du monde, puis d'autres choses ... L'interface utilisateur est proche de la fin, et le rendu est le dernier. Lorsque le jeu démarre pour la première fois, il n'y a pas de monde, de physique ou d'IA, donc ces étapes sont essentiellement ignorées et seul l'écran de titre s'affiche. Lorsque vous démarrez le jeu proprement dit, l'interface utilisateur envoie un message au système mondial pour qu'il s'allume, et il prend juste soin de lui-même. Gérer l'état du jeu signifie simplement activer et désactiver les différents systèmes. Chaque système possède son propre ensemble d'informations d'état qui est traité plus ou moins indépendamment de tous les autres (ce n'est pas totalementEn réalité, de nombreux systèmes agissent sur le même ensemble de données - le système d'interface utilisateur, par exemple, récupère des données du monde pour afficher des informations par exemple. Le système d'IA doit également examiner et envoyer des messages à des entités dans le monde).
la source
Voici comment j'organise mes états dans Lua + Love2d. Cela évite les longues instructions if / then.
Tout d'abord, je crée une classe de base qui contient les méthodes update (dt) et render (). Vous pouvez également lui donner des méthodes de gestion d'événements, comme onKeyDown (clé). J'appelle cette classe Stage, mais tout objet qui implémente les méthodes fonctionnera. Ensuite, je crée une instance de cette classe pour chaque état de jeu, en implémentant les méthodes nécessaires. Je crée ensuite une table clé / valeur avec le nom de l'état et l'instance de l'état. Ensuite, gardez une trace de currentState au niveau global afin que les états puissent le changer lorsqu'une certaine condition est remplie.
la source
Eh bien, bien que ce ne soit pas joli, c'est OK pour gérer les états de cette façon, OMI. Vous pouvez le rendre beaucoup plus propre en utilisant des fonctions pour chaque état, comme:
ou quelque chose d'autre vous dérange dans cette approche (je veux dire, sauf que la méthode de mise à jour est très longue)?
la source