문제

나는 개인 프로젝트에서 내가 생각하는 것을 모델링 할 패턴을 찾고 있었고, 수정 된 버전의 데코레이터 패턴이 작동하는지 궁금했습니다.

기본적으로 나는 캐릭터 속성이 장착 한 항목에 의해 수정되는 게임을 만들고자합니다. 데코레이터가 수정하는 방식은 이에 적합하지만, 나는 당신이 중간 데코레이터를 떨어 뜨릴 수있는 데코레이터를 본 적이 없다.

이런 식으로 데코레이터 패턴을 사용한 경험이 있습니까? 아니면 내가 잘못된 나무를 짖고 있습니까?

설명

"중간 데코레이터"를 설명하려면 예를 들어 내 기본 클래스가 설탕으로 장식 된 우유로 장식 된 커피이라면 (헤드 첫 번째 디자인 패턴으로 예제 사용) 우유는베이스 커피를 장식하고 장식 된 중간 데코레이터가 될 것입니다. 설탕으로.

더 많은 설명 :)

아이디어는 항목이 통계를 변경한다는 것입니다. 나는 데코레이터를 신발시키고 있다는 데 동의합니다. 나는 주 가방을 살펴볼 것이다. 본질적으로 나는 통계를 위해 단일 통화를 원하고 품목이 장착/장비가 없을 때 위/아래로 이동하기를 원합니다.

장비의 캐릭터 통계에 수정자를 적용하고 제외 할 때 다시 롤백 할 수 있습니다. 또는 통계가 모든 항목을 반복하고 통계를 계산할 때마다.

나는 여기서 피드백을 찾고 있습니다. 가위가 더 적절한 전기 톱을 사용하고 있다는 것을 알고 있습니다 ...

도움이 되었습니까?

해결책

To be honest, it sounds like you're really trying to fit a pattern where you don't really need one, just for the sake of using a pattern. Don't be that guy.

Now, if the weapons gave the character some extra strength/stam/hp or whatever, then it might be worth considering. But it doesn't sound like you're going to be modifying (or decorating) the properties of the character at all with these.

다른 팁

I see what you're trying to do, but one of the things to remember about patterns is that you shouldn't try to shoe-horn your design to fit a pattern. Patterns occur naturally - the behavior you're describing isn't really part of the Decorator Pattern.

With that said, I'd imagine that you're going to want to unequip a weapon via some unique ID, say:

Character.unequip(LIGHTSABER);

If you'd try to fit this into the Decorator Pattern, you'd have to keep track of the currently equipped items and then, after removing a weapon, you'd have to update the reference of the object decorating the LIGHTSABER to the one LIGHTSABER is decorating. That's a lot of work.

Instead, perhaps it's worth considering @Mitch's idea and let the character's weapons be help in a property bag. Remember that a character HAS-A set of weapons. To me, it seems like composition may be the way to go.

There are three answers to implementing propegated stats in a video game:

(1) this will satisfy any hobbist-game you will ever make (and pretty much every professional game as well):

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

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

(note the different GetStrength*() functions have nothing to do with each other)

(2) this will satisfy all games that don't have the word 'diablo' in the title:

 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) else

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

And honestly (3) was probably overkill.

Hmmm.. I'm thinking that maybe a command pattern would be a good solution to this problem. Here's what I mean:

This is your character class:

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

Here are some examples of commands:

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

Of course, this is just a suggestion and definitely open for debate, I'm not saying that this is the best or the only way to do this...

Just keep 2 sets of stats, your base stats and your effective stats. When you equip or unequip an item add or subtract from the effective stats where appropriate. Then you don't have to traverse your equipment list every time you want to know what your stats are.

I know this question is old, but this might help somone else if not the OP. Read this article, to understand how this sort of thing really should be done in games (by one of the devs who worked on the Tony Hawk games):

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

Compose your entities/game objects. For constructing entity behaviours in games, never, NEVER rely on inheritance, or on anything that itself relies on inheritance in any way -- this includes the decorator pattern as the OP suggested. You will be tying your own hands. Composition is THE way to go.

Are you looking for the Strategy pattern?

Why not code the weapons as follows:

1 = chainsaw 2 = shotgun 4 = rail gun

So now the sum of 6 can only mean that the character possesses the shotgun and the rail gun. This is a fast summary so you do not have to iterate through your list of dictionary of weapons. You still need some structure to contain the weapons, but at least you'll get speed with this approach. This presupposes that you can have only one weapon of each category, but many categories simultaneously.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top