6
votes

Système d'état de jeu C ++

Okay: Je suis assez nouveau à C ++ et les langues statiques dans son ensemble. Venir des années de rubis (et d'autres langues dynamiques), je ne sais pas si cela est possible.

Je fais un système d'état de jeu pour ... bien un jeu. Je veux rendre le système facile pour moi de couper et de coller dans d'autres jeux sans [ni peu de) changements. P>

Les deux choses que je veux améliorer sont la manière dont les états basculent et la voie Dans quels pointeurs d'état sont détenus. P>

Il pourrait y avoir n'importe quel nombre d'états, mais il y aura toujours au moins 2 à 3 états actifs dans la mémoire. P>

la laideur n ° 1 . strong> p>

J'ai actuellement une classe de gestionnaire d'état avec quelque chose comme ceci, il y a: p> xxx pré>

Cette approche fonctionne mais je ne me sens pas C'est très gentil. p>

est-il possible de passer un type? Puis appelez-vous neuf sur cela? P>

m_GameStates[m_CurrentState];


6 commentaires

Pourquoi y aura-t-il 2-3 États actifs en même temps?


Pour votre premier problème, pourriez-vous montrer la signature de la fonction contenant cet interrupteur? Afin de répondre correctement à la question, nous devons savoir à quoi ressemble la fonction et quel type les variables sont.


@Georg, quelques États resteront actifs pour permettre la commutation rapide, le menu principal / Menu de pause, etc. @jalf Pastie.org/1042747 Fonction de commutateur complet.


OK, j'ai édité la fonction complète dans votre question. :)


Est statisid A typedef pour int ou comment est-il défini?


Son type est défini par une énumération qui contient tous les états


6 Réponses :


2
votes

Utilisez une énumération (eration) pour définir tous les états possibles (c'est comme une liste avec des constantes). Il suffit de créer pour un objet une variable qui contient l'état et modifie la variable chaque fois que vous devez le changer.


1 commentaires

J'essaie d'éviter de définir une liste de tous les états possibles. Eh bien, j'essaie de savoir s'il y a une meilleure façon.



2
votes

Dès que vous dites des états, je pense au modèle d'état .

Fondamentalement, vous pouvez dériver un tas d'objets d'une classe de base de l'état. Toutes les actions liées à un état se produisent contre l'état actuel maintenu par le gestionnaire d'État. Les États passeront d'état à l'état via le gestionnaire.

Par exemple, vous pouvez avoir un état de pause et non utilisé, chacun avec un événement de boutonnière. Lorsque vous appuyez sur un bouton, l'état actuel est livré l'événement. Si c'est en pause, et que le bouton était le bouton de pause, passez à la non-utilisée. Vice versa pour non utilisé.


0 commentaires

0
votes

Pour votre premier problème, oui, vous pouvez passer dans un type, avec des mises en garde.

J'ai ajouté un commentaire sous votre question, demandant un peu plus d'informations. Jusqu'à ce que nous obtenions cela, je ne peux pas vraiment dire comment il devrait être fait, mais lisez sur les modèles.

Vous pouvez créer un modèle de fonction, qui peut être transmis un type , par exemple comme celui-ci: xxx

Il existe certaines limitations à cela, car les types doivent être spécifiés à la compilation, mais c'est une fonctionnalité de langue très puissante. < / p>

Une autre option, ce qui pourrait fonctionner mieux depuis que vous semblez avoir une association entre une variable ( MainState ) et un type ( mainmenu ), pourrait être le Utilisation de classes de traits. Encore une fois, je ne suis pas sûr de savoir exactement comment cela serait fait dans votre cas, car nous n'avons pas vu l'intégralité de la fonction (en particulier, quel type est MainState et comment / quand est Il a créé?)

Il pourrait également être possible de résoudre le problème par le polymorphisme, mais à nouveau, je devrais voir un peu plus du contexte à suggérer une solution.

Pour votre deuxième problème, vous pouvez utiliser la bibliothèque standard mappe : xxx

enfin, un peu vraiment important de conseils: < P> Arrêtez d'utiliser des pointeurs partout. Arrêtez d'appeler Nouveau pour créer de nouveaux objets. En règle générale, les objets doivent être créés sur la pile (au lieu de foo * f = nouveau foo; , juste faire foo f;

et Au lieu d'utiliser des pointeurs, vous voudrez souvent simplement copier l'objet lui-même. Alternativement, créer des références au lieu des pointeurs.

et lorsque vous do doivent utiliser des allocations de mémoire dynamiques, vous toujours ne devrait pas utiliser nouveau directement. Au lieu de créer un objet wrapper, qui interne alloue ce dont il a besoin avec neuf dans son constructeur et libère à nouveau dans le destructeur.

Si vous le faites correctement, il résout presque tous les maux de tête de la gestion de la mémoire.

La technique générale est appelée Raii .


4 commentaires

Merci pour les conseils du pointeur, tout a l'air vraiment cool merci.


Personnellement, je pense qu'un modèle est une sorte de surenvocasse pour cela. Cela fait des réflexions difficiles (plus difficiles) qui sont très faciles et simples.


@Insernickhere: Peut-être. Je l'ai mentionné parce que @Philck a demandé "est-il possible de passer un type?", Qui est à peu près le cas # 1 d'utilisation pour les modèles. Vous avez raison, ce n'est peut-être pas la meilleure solution dans ce cas particulier, mais je pense que cela vaut la peine de mentionner au moins l'option. :)


J'ajouterais également la mise en garde que votre recherche de carte insère un élément par défaut s'il n'est pas trouvé que vous devez utiliser Rechercher pour vérifier l'existence.



2
votes
void StateManager::changeState(StateID nextStateID)
{
     leaveState(actualState); 
     enterState(nextStateID);
}
I really like this one - as easy as it could be. ;-)What I want to tell you - I think doing creation/deleting your stats in the changeState Function is too much of logic in there - it just is supposed to change the state, right?Edit:
To come to your 2 question - I don't think using this array is really a waste - you are talking about 3 fields, not 300 or so. So if you like using arrays - go for it. If you don't, the map would be my choose, it makes things easy if you want to check if there is a state created or not and you are not limited to a magic number "maxStates". You could possible check if there is enough ram and then create X states, not fixed 2-3. 

0 commentaires

0
votes

1
votes

Pour générer des états, vous voulez une usine. De cette façon, l'ID d'état reste agréable un générique. Pour stocker des états, j'irais avec une STD :: map


0 commentaires