Question

Je recherchais un motif pour reproduire ce que je pensais faire dans un projet personnel et je me demandais si une version modifiée du motif du décorateur fonctionnerait.

En gros, je songe à créer un jeu dans lequel les attributs des personnages sont modifiés par les objets qu’ils ont équipés. La façon dont le décorateur empile ses modifications est parfaite pour cela. Cependant, je n'ai jamais vu de décorateur vous permettant de laisser tomber les décorateurs intermédiaires, ce qui se produirait lorsque les éléments ne sont pas équipés.

Quelqu'un a-t-il déjà utilisé le motif de décorateur de cette manière? Ou suis-je en train d'aboyer le mauvais arbre?

Clarification

Expliquer "Les décorateurs intermédiaires" si, par exemple, ma classe de base est le café qui est décoré avec du lait et décoré avec du sucre (comme dans l'exemple de Head first design patterns), le lait serait un décorateur intermédiaire puisqu'il décore le café de base et est décoré avec le sucre.

Encore plus de précisions:)

L'idée est que les articles changent les statistiques, je conviens que je suis en train de décorer le décorateur. Je vais regarder dans le sac d'état. Je souhaite essentiellement un point d’appel unique pour les statistiques et leur progression lorsque les éléments sont équipés / non équipés.

Je pourrais simplement appliquer les modificateurs aux statistiques des personnages pour les équiper et les restaurer lors de l’équipement. Ou chaque fois qu'une statistique est demandée, parcourez tous les éléments et calculez la statistique.

Je ne cherche que des commentaires ici, je suis conscient que je pourrais utiliser une scie à chaîne où des ciseaux seraient plus appropriés ...

Était-ce utile?

La solution

Pour être honnête, on dirait que vous essayez vraiment d’adapter un motif pour lequel vous n’avez pas vraiment besoin d’un motif, juste pour utiliser un motif. Ne sois pas ce mec.

Maintenant, si les armes donnaient au personnage une force supplémentaire / stam / hp ou quoi que ce soit, cela pourrait valoir la peine d'être pris en compte. Mais il ne semble pas que vous allez modifier (ou décorer) les propriétés du personnage avec celles-ci.

Autres conseils

Je vois ce que vous essayez de faire, mais l’une des choses à retenir concernant les motifs est que vous ne devriez pas essayer d’aligner votre motif sur un motif. Les motifs se produisent naturellement - le comportement que vous décrivez ne fait pas vraiment partie du motif de décorateur.

Cela dit, j'imagine que vous allez vouloir déséquiper une arme via un identifiant unique, par exemple:

Character.unequip(LIGHTSABER);

Si vous essayez d’adapter cela au motif de décorateur, vous devrez garder une trace des objets actuellement équipés, puis, après avoir retiré une arme, vous devrez mettre à jour la référence de l’objet décorant le LIGHTSABER. à celui que LIGHTSABER est en train de décorer. C'est beaucoup de travail.

Au lieu de cela, cela vaut peut-être la peine d’envisager l’idée de @ Mitch et de laisser les armes du personnage servir d’aide dans un sac de propriété. Rappelez-vous qu'un personnage possède un ensemble d'armes. Pour moi, il semble que la composition soit la solution.

Il existe trois réponses à la mise en œuvre de statistiques proportionnées dans un jeu vidéo:

(1) Cela satisfera tous les jeux hobbistes que vous ferez (et pratiquement tous les jeux professionnels):

character.GetStrength() {
  foreach(item in character.items)
    strFromItems += item.GetStrengthBonusForItems();
       foreach(buff in character.buffs)
    strFromBuffs += buff.GetStrengthBonusForBuffs();
  ...

  return character.baseStrength + strFromItems + ...;
}

(notez que les différentes fonctions GetStrength * () n'ont rien à voir entre elles)

(2) cela satisfera tous les jeux qui n'ont pas le mot 'diablo' dans le titre:

 character.GetStr() { ... // same as above, strength is rarely queried }
 character.GetMaxHP() { 
   if (character._maxHPDirty) RecalcMaxHP();
   return character.cachedMaxHP;
 }
 // repeat for damage, and your probably done, but profile to figure out
 // exactly which stats are important to your game

(3) sinon

 // changes in diablo happen very infrequently compared to queries, 
 // so up propegate to optimize queries.  Moreover, 10 people edit 
 // the stat calculation formulas so having the up propegation match 
 // the caculation w/o writing code is pretty important for robustness.

 character.OnEquip(item) {
     statList.merge(item.statlist);
 }

 character.GetStrength() {
     statList.getStat(STRENGTH);
 }

 statlist.getStat(id) {
     if (IS_FAST_STAT(id)) return cachedFastStats[id];
     return cachedStats.lookup(id);
 }

 statlist.merge(statlist) {
      // left for an exercise for the reader
 }

Et honnêtement (3) était probablement exagéré.

Hmmm .. Je pense qu'un modèle de commande serait peut-être une bonne solution à ce problème. Voici ce que je veux dire:

Ceci est votre classe de personnage:

Public class Character {

 //various character related variables and methods here...

 Command[] equipCommands;
 Command[] unequipCommands;

 public Character(Command[] p_equipCommands, Command[] p_unequipCommands) {

  equipCommands = p_equipCommands;
  unequipCommands = p_unEquipCommands;
 }

 public void itemEquiped(int itemID) {

  equipCommands[itemID].execute(this);
 }

 public void itemUnequiped(int itemID) {

  unequipCommands[itemID].execute(this);
 }
}

Voici quelques exemples de commandes:

public class SwordOfDragonSlayingEquipCommand implements ItemCommand{

 public void execute(Character p_character) {

  //There's probably a better way of doing this, but of the top of my head...
  p_character.addItemToInventory(Weapons.getIteM(Weapons.SWORD_OF_DRAGON_SLAYING));

  //other methods that raise stats, give bonuses etc. here...
 }
}

public class SwordOfDragonSlayingUnequipCommand implements ItemCommand{

 public void execute(Character p_character) {

  //There's probably a better way of doing this, but of the top of my head...
  p_character.removeItemFromInventory(Weapons.getIteM(Weapons.SWORD_OF_DRAGON_SLAYING));

  //other methods that lower stats, remove bonuses etc. here...
 }
}

Bien sûr, il ne s’agit là que d’une suggestion ouverte au débat, je ne dis pas que c’est la meilleure ou la seule façon de le faire ...

Conservez simplement 2 jeux de statistiques, vos statistiques de base et vos statistiques effectives. Lorsque vous équipez ou déséquipez un objet, ajoutez ou soustrayez des statistiques, le cas échéant. Dans ce cas, vous ne devez pas parcourir votre liste d’équipements à chaque fois que vous souhaitez connaître vos statistiques.

Je sais que cette question est ancienne, mais cela pourrait aider quelqu'un d'autre si ce n'est le PO. Lisez cet article pour comprendre comment ce genre de choses devrait vraiment être fait dans les jeux (par l’un des développeurs qui ont travaillé sur les jeux Tony Hawk):

http://cowboyprogramming.com/2007/01/05/ évoluer-votre-héritage /

Composez vos entités / objets de jeu. Pour construire des comportements d'entité dans les jeux, ne comptez JAMAIS sur l'héritage ou sur tout ce qui lui-même repose sur l'héritage - cela inclut le motif de décorateur proposé par le PO. Vous allez vous lier les mains. La composition est LA voie à suivre.

Recherchez-vous le modèle de stratégie?

Pourquoi ne pas coder les armes comme suit:

1 = tronçonneuse 2 = fusil de chasse 4 = pistolet sur rail

Alors maintenant, la somme de 6 ne peut que signifier que le personnage possède le fusil de chasse et le pistolet. Ceci est un résumé rapide afin que vous n'ayez pas à parcourir votre liste de dictionnaire d'armes. Vous avez encore besoin d'une structure pour contenir les armes, mais au moins vous allez avoir de la vitesse avec cette approche. Cela présuppose que vous ne pouvez avoir qu'une seule arme de chaque catégorie, mais plusieurs catégories simultanément.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top