Comment concevoir un schéma d'interaction d'objet de jeu efficace avec une architecture basée sur des composants?

14

C'est une question de conception ... Je suis sûr que cela pourrait être plus généralisé, mais j'ai du mal avec ça. Je m'interroge sur la conception des interactions d'objets de jeu - voici mon exemple (puzzle-plateforme 2D).

Supposons que le joueur essaie de progresser à travers un niveau. Il existe de nombreuses lumières qui peuvent être dirigées dans différentes directions. Voici un exemple de la façon dont ces objets lumineux pourraient interagir ...

  • Une lumière projette une plateforme qui permet au joueur de franchir un espace
  • Une lumière diminue les coefficients de frottement de tout ce qu'elle touche, une autre l'augmente
  • Une lumière annule les effets de toutes les lumières, ce qui ferait disparaître la plate-forme pendant que cette lumière est allumée et annulerait les modificateurs de friction
  • Etc...

Quelle est la meilleure façon d'aborder ce problème lors de l'utilisation d'une architecture de composants? Les composants de chaque objet majeur semblent évidents, ainsi qu'une manière claire de définir leurs effets sur l'environnement. Une classe pour "résoudre" l'interaction (semble que cela pourrait devenir un gâchis rapidement)? Une certaine utilisation du motif décorateur pour créer des objets combinés pour ceux qui interagissent à un moment donné? Une structure de données qui s'y prête?

Aussi, connecter l'audio à ces interactions? Il semble que la connexion audio au système soit comme la connexion de toute autre propriété, comme la visibilité ou le mouvement / collision d'un joueur.

De toute évidence, à mesure que de nouveaux composants sont ajoutés, il serait bien qu'il y ait un système robuste capable de gérer de nouveaux composants avec peu de modifications, mais je ne sais pas comment procéder pour le concevoir.

Autres informations: Le moteur que j'utilise est un moteur XNA appelé IceCream .

Christopher Horenstein
la source
2
Il y a cependant une vraie question ici, par opposition à la "question" sur le lien que Joe donne.
dash-tom-bang
2
ne voyez pas le dupe, la question est de savoir comment concevoir les exigences d'un jeu spécifique dans le code, en utilisant un système de composants (@Christopher: en mentionnant lequel aiderait cependant, utilisez-vous Unity? Torque? Propriétaire?)
LearnCocos2D
2
Au fait, j'aime votre idée de gameplay =)
Nailer

Réponses:

5

Dans un système orienté objet, la seule vraie réponse à la question de savoir quelle est la meilleure façon de faire X est que vous devez le faire de la manière la plus simple à laquelle vous pouvez penser pour mettre quelque chose en marche, puis le changer quand un une expression plus facile devient apparente. Vous soucier de choisir le bon modèle avant d'avoir écrit un code est un bon moyen de vous retrouver avec la mauvaise réponse dès le départ; laissez toutes les pensées des motifs et des composants se dissiper et suivez simplement ces étapes, en commençant d'où vous êtes aujourd'hui (en supposant que vous avez mis en œuvre un composant léger):

  1. Ajoutez du code au composant léger sur les plateformes de projet. (Obtenez ce travail.)
  2. Copiez ce composant dans un nouveau composant, supprimez les éléments de la plate-forme et ajoutez du code pour réduire la friction des objets appropriés. (Faites fonctionner cela, vérifiez que # 1 fonctionne toujours.)
  3. Copiez ce composant dans un nouveau composant, supprimez le "nouveau" code et ajoutez des éléments pour désactiver les effets des autres composants. (Faites fonctionner cela, puis vérifiez que # 1 et # 2 fonctionnent toujours.)

À ce stade, vous aurez (probablement) une tonne de code dupliqué. Extraire le code commun dans des fonctions ou une autre classe (peut-être une classe de base) ou tout ce qui semble approprié. Ce n'est pas parce que vous avez commencé avec un "composant léger" que LightComponent est une base appropriée; il se pourrait que le code composant le composant léger ne soit pas vraiment un "composant" en soi et peut-être qu'il sera mieux représenté par un ensemble de fonctions ou même une classe distincte qui est agrégée dans vos nouveaux composants (en tant que variable membre ).

dash-tom-bang
la source
Je marque cela comme la réponse, car il répond vraiment "Comment dois-je concevoir ...". Merci pour cela, cela m'a définitivement mis sur la bonne voie.
Christopher Horenstein
2

En termes généraux, lorsqu'un objet de type A interagit avec un objet de type B, vous voulez avoir un effet C. Cela s'appelle "double répartition" et est très difficile à faire avec élégance dans des langages de type C.

Le moyen efficace mais difficile à entretenir n'est qu'un tas de commutateurs et d'instructions if, selon les types de vos objets. Vous vous sentirez sale en l'écrivant mais cela fera le travail.

Le modèle de visiteur est une solution plus robuste qui masque la commutation de type désagréable, mais peut être lourde à configurer.

Normalement, tout type de changement de type dans votre code est une odeur, mais ici, vous essayez de généraliser le polymorphisme, qui change normalement les fonctions en fonction d'un seul type, pour changer les fonctions en fonction de deux types. Le polymorphisme est un fondement de la POO, donc ce n'est pas une odeur.

tenpn
la source
2

Laisse moi voir. C'est juste quelque chose que j'ai préparé dans ma tête pendant que j'écrivais, donc désolé si je manque quelque chose.

Obtenez tous les nœuds lumineux à une distance raisonnable autour de votre mec.

Pour chaque lumière, vous rendez un polygone représentant sa zone d'effet à un objet framebuffer. Ainsi, un cône de lumière créerait un cône d'un type de pixels dans votre FBO. Rendez chaque type de nœud en passes avec la priorité appropriée. Vous pouvez encoder des informations dans chaque pixel comme le canal vert pourrait être la fricition, le rouge la gravité, le bleu et l'alpha quelque chose d'autre.

Des techniques de mélange de couleurs intelligentes pourraient alors créer des effets intéressants. Chaque niveau peut avoir ses propres règles de mélange.Vous pouvez également ajouter un ombrage de fragment pour des effets dynamiques psychédéliques comme la gravité pulsatoire, etc.

Enfin, vérifiez simplement quels pixels votre mandude touche, et recalculez le bitmap chaque fois que vous vous approchez des bords de la zone précalculée.

Scetch grossier réalisé en 2 minutes pour illustrer mon idée:

Illustration

Edit: En pratique, cela signifie que la seule chose dont vous avez besoin est un composant lumineux émettant une certaine couleur. Les règles liées à quelle couleur fait ce qui peut être complètement ailleurs. Vous pouvez encoder beaucoup de données dans les 32 bits que vous avez pr pixel. Alternativement, vous pouvez avoir plusieurs FBO contenant des attributs différents qui ne s'influencent pas mutuellement. Vous pouvez avoir un FBO gravité / friction et un FBO collision 1 bit. Si vous choisissez cela, vous devrez bien sûr signaler dans quel FBO votre lumière doit être restituée.

Cloueur
la source
Merci pour votre participation. J'apprécie vraiment les visuels, et cela m'a vraiment fait réfléchir sur la façon dont le mécanicien pouvait travailler en coulisses.
Christopher Horenstein
Hé, pas de problème. Je sais que cela n'a pas répondu à votre question exacte, mais certains problèmes nécessitent des solutions spécialisées. Bonne chance!
Nailer
0

Pattern Observer est l' une des meilleures solutions. Le message sera envoyé uniquement aux objets (composants) qui s'y intéressent vraiment. Le destinataire doit donc s'abonner à ce type de message / événement.

Il existe de nombreuses implémentations de signal / slot. Par exemple, en C ++ il y a une bibliothèque sigslot

Pour plus d'informations, lisez les signaux Qt et les slots .

en haut à droite
la source