Вопрос

Я искал шаблон для моделирования того, что я собираюсь сделать в личном проекте, и мне было интересно, сработает ли модифицированная версия шаблона декоратора.

В основном я подумываю о создании игры, в которой атрибуты персонажей изменяются в зависимости от того, какими предметами они экипированы.Способ, которым декоратор объединяет свои модификации, идеально подходит для этого, однако я никогда не видел декоратора, который позволял бы вам отбрасывать промежуточные декораторы, что и произошло бы, если бы элементы были необорудованы.

Есть ли у кого-нибудь опыт использования шаблона декоратора таким образом?Или я лаю не на то дерево?

Разъяснение

Чтобы объяснить "Промежуточные декораторы", если, например, моим базовым классом является coffe, который украшен молоком, которое украшено сахаром (используя пример в шаблонах дизайна Head first), milk будет промежуточным декоратором, поскольку он украшает базовый кофе и украшен сахаром.

Еще Одно уточнение :)

Идея в том, что предметы меняют статистику, я бы согласился, что я включаю в это декоратора.Я загляну в государственную сумку.по сути, я хочу иметь единую точку доступа к статистике, и чтобы они увеличивались / уменьшались, когда предметы оснащены / необорудованы.

Я мог бы просто применить модификаторы к статистике персонажей при экипировке и откатить их при экипировке.Или всякий раз, когда запрашивается статистика, перебирайте все элементы и вычисляйте статистику.

Я просто ищу здесь отзыв, я знаю, что, возможно, использую бензопилу, где ножницы были бы более уместны...

Это было полезно?

Решение

Честно говоря, это звучит так, как будто вы действительно пытаетесь подогнать шаблон там, где он вам на самом деле не нужен, просто ради использования шаблона.Не будь таким парнем.

Теперь, если бы оружие давало персонажу дополнительную силу / stam / hp или что-то еще, тогда, возможно, стоило бы подумать.Но это совсем не похоже на то, что вы собираетесь изменять (или украшать) свойства персонажа с их помощью.

Другие советы

Я понимаю, что вы пытаетесь сделать, но одна из вещей, которую следует помнить о шаблонах, заключается в том, что вы не должны пытаться подгонять свой дизайн под шаблон.Шаблоны возникают естественным образом - поведение, которое вы описываете, на самом деле не является частью шаблона декоратора.

С учетом сказанного, я бы предположил, что вы захотите снять оружие с вооружения, скажем, с помощью какого-нибудь уникального идентификатора:

Character.unequip(LIGHTSABER);

Если бы вы попытались вписать это в шаблон декоратора, вам пришлось бы отслеживать текущие предметы экипировки, а затем, после удаления оружия, вам пришлось бы обновить ссылку на объект, украшающий СВЕТОВОЙ МЕЧ, на тот, который украшает СВЕТОВОЙ МЕЧ.Это большая работа.

Вместо этого, возможно, стоит рассмотреть идею @Mitch и позволить оружию персонажа быть подспорьем в сумке с имуществом.Помните, что У персонажа ЕСТЬ -Набор оружия.Мне кажется, что композиция - это правильный путь.

Есть три способа реализовать расширенную статистику в видеоигре:

(1) это удовлетворит любую игру для любителей, которую вы когда-либо создадите (и практически любую профессиональную игру тоже).:

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

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

(обратите внимание, что различные функции GetStrength *() не имеют ничего общего друг с другом)

(2) это подойдет для всех игр, в названии которых нет слова "diablo":

 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) остальное

 // 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
 }

И, честно говоря, (3), вероятно, было излишеством.

Хммм..Я думаю, что, возможно, командный шаблон был бы хорошим решением этой проблемы.Вот что я имею в виду:

Это ваш класс персонажей:

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);
 }
}

Вот несколько примеров команд:

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...
 }
}

Конечно, это всего лишь предложение и, безусловно, открыто для обсуждения, я не говорю, что это лучший или единственный способ сделать это...

Просто сохраните 2 набора статистики, вашу базовую статистику и вашу эффективную статистику.Когда вы снаряжаете предмет, добавляйте или вычитайте из него эффективные характеристики, где это уместно.Тогда вам не придется просматривать список своего снаряжения каждый раз, когда вы захотите узнать, какова ваша статистика.

Я знаю, что этот вопрос устарел, но это могло бы помочь кому-то еще, если не оператору.Прочтите эту статью, чтобы понять, как на самом деле следует делать подобные вещи в играх (автор - один из разработчиков, работавших над играми Tony Hawk).:

http://cowboyprogramming.com/2007/01/05/evolve-your-heirachy/

Создавайте свои сущности / игровые объекты.Для построения поведения сущностей в играх никогда, НИ в коем случае не полагайтесь на наследование или на что-либо, что само каким-либо образом полагается на наследование - это включает шаблон декоратора, как предложил OP.Вы сами свяжете себе руки.Композиция - это правильный путь.

Вы ищете шаблон Стратегии?

Почему бы не закодировать оружие следующим образом:

1 = бензопила 2 = дробовик 4 = рельсовое ружье

Таким образом, теперь сумма 6 может означать только то, что у персонажа есть дробовик и рельсовая пушка.Это краткое изложение, так что вам не придется перебирать список оружия по словарю.Вам все еще нужна какая-то структура для размещения оружия, но, по крайней мере, при таком подходе вы получите скорость.Это предполагает, что у вас может быть только одно оружие каждой категории, но несколько категорий одновременно.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top