Gérer des listes de différents types d'entités - existe-t-il un meilleur moyen?

9

Je développe un jeu spatial 2D pour les appareils mobiles, mais il devient vraiment complexe et ma solution est vraiment déroutante et produit de nombreux segments de code répétés.

J'ai une classe mondiale dans laquelle j'ai des listes multibles d'objets différents comme:

List<Enemy> enemys;
List<Projectile> projectiles;
List<Collectable> collectables;
List<Asteroid> asteroids;
List<Effect> effects;
..

Chaque liste est mise à jour par la classe mondiale. mais ce n'est pas tout .. Chaque ennemi a une liste de moteurs et une liste de lanceurs d'armes qui sont mis à jour par l'ennemi. Désormais, chaque moteur ajoute des effets de feu aux «effets» de la liste mondiale, et chaque lanceur d'armes ajoute des projectiles à la liste des «projectiles» de la liste mondiale. Toutes ces classes ont des paramètres différents, j'ai donc besoin d'une mise à jour supplémentaire ET d'une fonction de rendu supplémentaire pour chaque classe.

Au moins, ils sont tous des enfants de 'GameObject' qui leur fournit des éléments de base comme la position, la vitesse et les vecteurs d'accélération, des polygones de délimitation et des fonctions comme applyForce et une machine à états finis

Existe-t-il une façon meilleure ou plus courante de procéder? comme une classe fourre-tout qui contient tous les paramètres et méthodes possibles pour tous les différents objets. (Je pense que cela produirait un code encore plus déroutant)

Écrou
la source
Ceci est similaire à ma question: gamedev.stackexchange.com/questions/22559/… Je suggère de regarder les réponses qui lui ont été données.
Derek

Réponses:

5

Existe-t-il une façon meilleure ou plus courante de procéder? comme une classe fourre-tout qui contient tous les paramètres et méthodes possibles pour tous les différents objets.

Oui, cela s'appelle une architecture . Jetez un œil ici pour plus de détails.

Cela permettrait à une seule liste d'entités de votre classe mondiale:

List<Entity>

C'est un exemple de composition sur héritage .

Laurent Couvidou
la source
3

Dans les limites de votre question d'origine, une option serait de répartir les listes en actions au lieu de types comme ceux que vous avez. Par exemple, vous auriez un List<HasAI>et un pour List<Collidable>et lorsque vous créez un nouvel objet, il s'ajoute à la liste d'actions dont il a besoin, lorsque l'objet est détruit, il se supprime de ces listes. Un objet peut figurer sur plusieurs listes.

La deuxième étape de cette option consiste à refactoriser vos classes d'une hiérarchie en une hiérarchie qui utilise des interfaces, de sorte que votre type HasAI est une classe qui implémente l'interface IBrains à titre d'exemple. Correspondant que le List<HasAI>seul nécessite que les objets aient l'interface IBrains.

Cela devrait aider à nettoyer une partie de la complexité.

Patrick Hughes
la source
2

Je pense que ce que vous devez faire est d'abstraire le rendu dans ses propres classes, je pense qu'un pour le joueur et un pour l'ennemi (ou peut-être juste un pour le joueur, puis en créer une instance pour le joueur et l'ennemi - pas sûr à 100% de votre conception de jeu.)

Vous pouvez utiliser un modèle de visiteur pour laisser le moteur de rendu tourner autour des divers objets et décider quoi dessiner, ce qui pourrait être moins complexe.

nycynik
la source
2

Utiliser une classe de base et s'appuyer sur le polymorphisme est une très bonne idée. Mais il existe des approches alternatives. Il y a deux articles de Noel Llopis qui valent la peine d'être lus. J'ai récemment étudié la conception orientée données et je pense qu'elle a un certain mérite.

Les articles sont ici et ici . Cela peut simplifier un peu plus votre code que le polymorphisme. Mais comme tout YMMV, jetez un œil et voyez si cela correspond à ce que vous essayez de réaliser. Le polymorphisme utilise l'héritage et le DOD utilise l'agrégation a des avantages et des inconvénients, alors choisissez votre poison.

Britchie
la source
1

Vous pouvez le faire en utilisant la POO et surtout le polymorphisme.

Fondamentalement, vous devez créer une classe de base, dont toutes les entités de jeu héritent. Cette classe de base est aussi abstraite que possible, elle contiendra des éléments tels qu'une fonction de création, de mise à jour et peut-être de destruction.

Ensuite, vous dérivez tous vos autres objets de jeu de cette classe. Vous devrez probablement également ajouter une sorte de réflexion dans votre code si votre langue ne le prend pas en charge, pour faire des choses plus avancées, mais c'est évitable si vous savez comment structurer correctement votre héritage.

Marlock
la source
1
Il l'a déjà fait - toutes ses classes sont des enfants de GameObject. Il lui suffit de transformer sa série de listes en une seule liste de GameObjects.
SomeGuy