Attention, c'est une longue question! J'implémente un jeu de cartes Solitaire en C++ sur Win32, et après avoir demandé this question, il devient clair que j'ai besoin d'un peu de conseils concernant la conception de classe réelle plutôt que des détails de mise en œuvre. J'utilise un modèle de contrôleur de vue modèle pour implémenter le jeu. Le modèle est le jeu, les cartes, les colonnes et l'historique des mouvements. La vue est responsable de la peinture à l'écran et le contrôle responsable de la gestion des messages et de la minuterie.Est-ce que le stockage d'itérateurs dans cette classe est imprudent? Sinon, comment parcourir cette séquence?
L'aspect du jeu que j'essaye actuellement de mettre en application est l'histoire d'action, qui appartient au Model
- je veux pouvoir "défaire" et "refaire" n'importe quel Action
.
Je décris un objet Move
comme un mouvement atomique d'une seule carte d'un CardPile
à un autre. Et j'ai décrit un Action
comme consistant en un ou plusieurs Moves
. par exemple. un accord sera 10 Moves
du Deck
à un particulier Column
. (Deck
et Column
sont simplement des spécialisations de CardPile
).
Je définis l'action comme une suite de déplacements, et j'ai fourni certaines fonctions à GetCurrentMove() et à Advance() un déplacement lorsqu'il a été effectué.
class Action
{
public:
void SetMoves(std::deque<Move> dmoves){ _m_deque = dmoves; }
void Advance();
std::deque<Move>::const_iterator GetCurrentMove();
private:
std::deque<Move> _m_deque;
std::deque<Move>::const_iterator currentmove;
};
Lorsque vous traitez (ou la mise en place, ou défaisant), ces Move
objets sont données pour une animation. Je dois être en mesure d'accéder à un seul objet Move
à la fois. Je récupère le Move
, l'analyse en coordonnées x et y puis lance une animation pour déplacer une carte d'un endroit à un autre à l'écran. Lorsque la carte a atteint sa destination, je tire un autre Move
de la deque.
J'ai été conseillé par d'autres avec plus d'expérience, de ne pas stocker des itérateurs dans la classe Action
. Le STL ne le fait pas et il y a apparemment de bonnes raisons.
Mais ma question est - est-ce que je n'ai pas avoir pour stocker les itérateurs dans la classe Action
? Vous voyez à la fois mon modèle et vue besoin d'accéder à l'Move
actuel, alors où puis-je stocker cet itérateur qui fait référence à l'actuel Move
... à l'intérieur du contrôleur?
Mon animation de jeu est basé (très large) sur ce modèle:
void control.game_loop(message)
{
switch(message)
{
case TIMER:
{
if(view.CardHasReachedDestination())
{
game.AdvanceAnimation();
if(!game.AnimationFinished())
view.Parse(game.GetNextMove());
}
view.MoveCardXY();
view.PaintToTheScreen();
controller.StartTheTimerAgain();
}
}
}
Meilleurs voeux,
BeeBand
Mais sûrement pour animer dans l'ordre inverse, vous devez faire plus de t han animer la série d'actions dans l'ordre inverse - chaque action elle-même doit également être inversée. – James
@Autopulated: J'ai mentionné les itérateurs inversés uniquement parce que dans sa précédente question, il avait posé des questions sur les itérateurs en sens inverse et en sens inverse. Vous avez raison: pour inverser l'animation (par exemple, pour annuler un mouvement), vous devez également inverser chaque animation. –
@Both: re. animation inverse. Oui sur le 'Annuler' J'ai une fonction view.ParseUnMove(), par opposition à ParseMove(), qui inverse la source et la destination 'CardPiles' - ceci crée une animation inverse. – BeeBand