Quelle est l'approche orientée objet correcte pour la conception de classes dans le développement de jeux?

31

Je suis en train de développer un jeu basé sur des sprites 2D pour Windows 7 Phone, en utilisant XNA. La formation et les didacticiels disponibles sont assez utiles, mais le problème auquel je suis confronté est que chacun d'eux aborde la conception de sa classe différemment, et le code n'est pas particulièrement bien factorisé. Par conséquent, il m'a été difficile d'acquérir une bonne compréhension des responsabilités que je devrais confier à une classe particulière.

Par exemple, je pourrais avoir une classe de sprite de base BaseSpritequi sait se dessiner, vérifier les collisions, etc. Je pourrais alors avoir une AnimatedSpriteclasse qui saurait naviguer dans sa feuille de sprite, une ExplodingSpriteclasse, etc. Cette technique est illustrée dans l'exemple Space Invaders dans les documents de la session 2 de Windows 7 Phone Jumpstart .

Alternativement, je pourrais plutôt placer l'essentiel du rendu et de l'exécution de la responsabilité du jeu dans une GameScreenclasse; cette classe et ses classes dérivées se comportent davantage comme des formulaires ou des pages Web en termes de responsabilités. Les classes de sprites sont des conteneurs plus simples avec beaucoup moins de logique.

Il s'agit de la technique utilisée dans le jeu Alien Sprite du Kit de formation Windows 7 Phone et d'autres exemples de gestionnaire d'état du jeu.

Quelle est l'approche orientée objet correcte pour la conception de classes dans le développement de jeux?

Josh E
la source

Réponses:

26

J'utilise une approche plus orientée composants, où vous auriez une classe Sprite qui a des composants comme Visual, Collision, Animation, Input, etc. Avec cette approche, je ne finis pas par avoir une hiérarchie de classe profonde (ce qui est bien) .

Pour plus d'informations sur la conception orientée composants, cliquez ici .

thbusch
la source
2
+1 l'article que vous avez lié était fantastique. J'étais tellement concentré sur le design pur OO, j'ai complètement ignoré le modèle de type composant / décorateur.
Josh E
1
Le modèle de composant n'est pas vraiment "moins pur" OO :)
Srekel
2
Effectivement. OO est souvent assimilé à l'héritage. Mais l'héritage n'est qu'un outil offert par OO, la composition en est un autre.
haffax
Oui. J'aurais dû être plus précis dans ma formulation; ce que je voulais dire, c'est que je me suis beaucoup concentré sur le côté héritage de OO au lieu de penser aux modèles de conception OO / autres aspects OO qui pourraient m'aider à réaliser ce que je voulais.
Josh E
Bien qu'une approche basée sur la comosition soit assez évidente et utilisée fréquemment, je n'ai pas encore trouvé de solution pour garder le composant de rendu portable. Tout indice serait génial.
Andreas
11

Dans les jeux, le modèle de composant est une solution courante.

munificent
la source
c'est un autre article fantastique - vaut bien la lecture.
Josh E
1
Super, super, super article!
Kevin
6

Les principes SOLID s'appliquent autant à la conception de code de jeu qu'à toute autre profession - au moins jusqu'à ce que vous arriviez à l'optimisation, donc j'utiliserais votre premier exemple comme point de départ.

J'irais plus loin, car BaseSprite semble avoir tendance à devenir une mégaclasse. Le principe de responsabilité unique impose que la collision, le rendu et la navigation soient tous gérés par des composants, plutôt que par des entrées individuelles dans une hiérarchie de classes. La classe de détention de tous ces composants ne devrait gérer que les positions du monde entre eux.

tenpn
la source
5

Pour les derniers projets, je me suis davantage penché vers une approche de style MVC.

Au début, nous ne savions pas si cela fonctionnerait, mais cela a parfaitement fonctionné.

Modèle

Les objets de données. Juste les données pures. Aucun comportement, aucun rendu.

Manager de données. Il suffit de gérer des "listes" d'objets de données. (Peut également être amélioré pour prendre en charge la mise en commun.)

Vue

Nous les appelons des moteurs de rendu. Pour chaque type d'objet de données, il existe un rendu. Lorsqu'il est appelé avec un gestionnaire, il rendra tous les objets de cette liste.

Manette

Identique aux rendus, mais contrôle le comportement.

Exemple

Le ShipManager a une liste de navires. Le ShipController déplacera les navires en fonction de leur état. Le ShipRenderer rendra les navires en fonction de leur état.

Pourquoi

De cette façon, la vue et la logique sont strictement séparées. Cela rend le portage vers une nouvelle plate-forme assez facile. L'optimisation de la disposition des données à l'intérieur du XxxManager est également très simple.

Andreas
la source
2
Je vous vote parce que j'en ai marre de voir plus ou moins nu "Use MVC" comme réponse acceptable. Si vous développez sur une plate-forme moderne, vous utilisez déjà MVC à plusieurs niveaux. Ce n'est pas une réponse spécifique, et ce n'est pas une bonne réponse, car elle ne dit pas aux gens comment structurer les classes, ce qui est spécifique à la tâche / au domaine. Vous vous retrouvez avec beaucoup de gens qui écrivent "classe Modal ...; classe View ...; classe Controller ..." MVC est un modèle avec beaucoup de bonne puissance explicative de haut niveau quand on parle de code existant. Ce n'est pas un modèle avec beaucoup de bon pouvoir de planification.
4
@Joe, je comprends votre point de vue, mais trouvez votre choix de mots inutile grossier. Je viens d'expliquer comment nous procédons. Étant donné que le choix d'architecture de niveau supérieur rend le choix de conception de niveau inférieur obsolète, je considère que c'est une réponse valable.
Andreas