Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

  1. #1
    Candidat au Club
    Best-practices : Design pattern pour gérer des informations de niveau vue
    Bonjour,

    Cette question porte sur les meilleures pratiques et l'organisation des classes pour un jeu (indépendemment du langage).
    Navré si elle n'est pas dans la bonne catégorie, j'ai eu du mal à choisir.


    Considérons que je souhaite développer un jeu d'échec. Je vais avoir un modèle représentant mon jeu, l'échiquier, les différents pions tout cela dans organisés dans plusieurs classes. Je vais certainement avoir une classe Piece, qui représentera une pièce sur l'échiquier, et qui aura entre autres les attributs :

    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    int boardX
    int boardY


    Ces attributs représentent la position de la pièce sur l'échiquier, dans le système de coordonnées de l'échiquier (case (0,0) à (7,7)). D'un point de vue modélisation, une pièce est forcément sur une case (et non à cheval entre deux).

    Quand le controlleur de jeu va vouloir opérer une action sur le jeu, il va probablement appeler une ou lpusieurs fonctions de notre modèle de jeu qui va immédiatement changer, entre autres, les coordonnées d'une pièce.

    Ca c'est pour le point de vue modèle de données. Voyons maintenant d'un point de vue Vue (dans le pattern MVC)

    La vue va faire le rendu de l'échiquier et des pièces qu'il contient. Elle va certainement avoir une référence vers les classes du modèle de jeu, va éventuellement s'enregistrer à des évènements du modèle, puis obtenir les positions des pièces dont elle a besoin. Pour dessiner la scène, la vue va donc itérer à travers le modèle de jeu pour obtenir les coordonnées des pièces (et convertir du système de case en pixels). Jusqu'ici tout va bien.

    Maintenant supposons que je veuille ajouter des animations, et qu'une pièce se déplace en 1 seconde.

    La vue a une référence vers le modèle de jeu, mais le modèle de jeu n'a pas l'information de la vraie position en pixel des pièces pendant leurs mouvement. Alors on peut imaginer une nouvelle classe pour gérer ces informations, disons une classe GraphicPiece, contenant une référence vers la Piece sous-jacente et deux attributs :

    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    int pixelX
    int pixelY


    Avant de poser les questions, dans cet exemple, j'ai utilisé un jeu d'échec et un exemple trivial, mais le cas se pose pour un modèle de donnée bien plus complexe, composé de plusieurs éléments différents, avec des interconnections entre eux, et qui évoluent au fil du jeu.

    Q1 : Ou est-ce que les instances de GraphicPiece devraient-elles être stockées ? Doit-on privilégier un modèle orienté-vue comme étant un duplicata du modèle de jeu mais contenant uniquement les informations de niveau vue ? Si oui cela lève d'autres problèmes comme la synchronisation du modèle orienté-vue quand le omdèle de jeu évolue. De plus, si la vue utilise des informations à la fois des deux modèles, il pourrait subvenir des incohérences (le modèle orienté-vue a des évolution progressives dans le temps, quand le modèle de jeu voit ses états modifiés instantanément).

    Q2 : Quand la vue fait son rendu, elle va utiliser le modèle de jeu pour itérer sur les pièces qui doivent être affichées. Mais la classe Piece n'a pas de référence vers la classe GraphicPiece donc la vue n'a pas de moyen de trouver les coordonnées de la pièce. Utiliser une map<Piece,GraphicPiece> est à écarter (over-killed et peu performant)

    Q3 : La classe Piece ne peut pas avoir une référence vers une GraphicPiece sinon cela casserait le principe d'isolation de la logique métier de la vue. Au pire, une Piece peut avoir un pointeur générique ou Object qui contiendra une instance de GraphicPiece plus tard downcastée, mais ce n'est vraiment pas une solution élégante.

    Q4 : Si j'essaie de résumer les problèmes levés : Quel design et organisation de classes est adapté pour qu'une vue puisse puisse accéder efficacement aux informations d'un modèle de jeu (potentiellement complexe) et à des informations additionnelles de niveau vue ? Sur quel objet ou modèle la vue devraient itérer pour faire le rendu des Piece en ayant accès à toutes ces informations ?

    J'espère avoir réussi à énnoncer le plus clairement possible la problèmatique à laquelle je fais face.
    Merci en tout cas d'avoir lu jusqu'ici.

    Stéphane

  2. #2
    Rédacteur/Modérateur

    Le rendu/moteur graphique se moque des cases du gameplay. Il a son propre système de coordonnées qui correspond que l'on va appeler les coordonnées world.
    Le rendu/moteur graphique se moque en fait complètement des éléments gameplay. Que tu aies des cases, pions etc, tout ce qui l'intéresse c'est les éléments graphiques à afficher (un cube de couleur, une image, un objet 3d, ...)

    Le gameplay utilise un système de coordonnées en case. Déjà le niveau 0 c'est d'avoir une structure Position ou Case qui comporte les 2 coordonnées et non 2 variables.
    Le gameplay possède le pointeur vers l'éléments graphique utilisé par le moteur. C'est le gameplay qui s'occupe de le charger, puisque c'est lui qui sait ce que ce doit être (couleur de case, type de pièce, ..).
    Quand le gameplay déplace une pièce sur le plateau, il met à jour la position dans le world, en fonction des spécificités et conversions que le gameplay a décidé.
    Le gameplay décide des conversions Gameplay<>World. S'il décide qu'une case gameplay a une taille world de 32*32, alors un pion en (1,1) sera en (32,32) dans le world.
    Les conversions seront sûrement un poil plus complexe, parce que tu vas vouloir positionner la pièce au milieu de la case, et non sur son bord.
    Tu veux sûrement pas non plus téléporter les pièces mais les voir se déplacer. Donc il y aura une machine à état qui déplace la pièce légèrement à chaque frame, jusqu'à atteindre sa destination.
    Pensez à consulter la FAQ ou les cours et tutoriels de la section C++.
    Un peu de programmation réseau ?
    Aucune aide via MP ne sera dispensée. Merci d'utiliser les forums prévus à cet effet.

###raw>template_hook.ano_emploi###