我正在寻找一种模式来模拟我正在考虑在个人项目中做的事情,我想知道装饰模式的修改版本是否会起作用。
基本上我正在考虑创建一个游戏,其中角色属性被他们所配置的项目修改。装饰器堆叠它的修改的方式是完美的,但是我从来没有见过允许你删除中间装饰器的装饰器,这是物品没有装备时会发生的情况。
有没有人有这种方式使用装饰器模式的经验?还是我在错误的树上吠叫?
澄清
要解释“中级装饰者”,例如我的基类是装饰着用糖装饰的牛奶的咖啡(使用头部第一个设计图案中的例子)牛奶将是装饰基础咖啡的中间装饰者,并由糖装饰。
更多澄清:)
这个想法是项目改变了统计数据,我同意我正在将装饰者变成这个。我会看看状态包。基本上我想要一个单点调用统计数据,并且当项目配备/不配备时,它们可以上下移动。
我可以将修改器应用于装备上的角色统计数据,并在不等时将其回滚。或者,当要求统计数据迭代所有项目并计算统计数据时。
我只是在这里寻找反馈意见,我知道我可能会使用电锯,剪刀会更合适...
答案 0 :(得分:2)
说实话,听起来你真的想要一个你并不真正需要的模式,只是为了使用一个模式。不要那个人。
现在,如果武器给予角色一些额外的力量/ stam / hp或其他什么,那么它可能值得考虑。但听起来你根本不会修改(或装饰)角色的属性。
答案 1 :(得分:2)
我看到你正在尝试做什么,但要记住关于模式的一件事是,你不应该试图用你的设计来装饰图案。模式自然发生 - 您描述的行为实际上并不是Decorator模式的一部分。
话虽如此,我想你会想要通过一些独特的ID来取消武器,比如说:
Character.unequip(LIGHTSABER);
如果您尝试将其装入装饰器模式,则必须跟踪当前装备的物品,然后在移除武器后,您必须更新装饰LIGHTSABER的物体的参考一个LIGHTSABER正在装饰。这是很多工作。
相反,也许值得考虑@Mitch的想法,让角色的武器在财产袋中得到帮助。记住一个角色有一套武器。对我来说,似乎构图可能是要走的路。答案 2 :(得分:1)
嗯..我在想,也许一个命令模式可以很好地解决这个问题。这就是我的意思:
这是你的角色类:
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...
}
}
当然,这只是一个建议,绝对可以辩论,我不是说这是最好或唯一的方法来做到这一点......
答案 3 :(得分:1)
在视频游戏中实施推定统计数据有三个答案:
(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)这将满足标题中没有“暗黑破坏神”一词的所有游戏:
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)可能有点矫枉过正。
答案 4 :(得分:1)
只需保留2组统计数据,基本统计数据和有效统计数据。装备或装备物品时,在适当的情况下增加或减少有效统计数据。然后,每当您想知道自己的统计数据时,就不必遍历设备清单。
答案 5 :(得分:1)
我知道这个问题已经过时了,但如果不是OP,这可能对其他人有所帮助。阅读这篇文章,了解在游戏中应该如何做这种事情(由一位参与Tony Hawk游戏的开发者):
http://cowboyprogramming.com/2007/01/05/evolve-your-heirachy/
撰写您的实体/游戏对象。对于在游戏中构造实体行为,永远不要依赖继承,或者依赖于任何依赖于继承的任何东西 - 这包括OP建议的装饰模式。你将自己动手。作文是要走的路。
答案 6 :(得分:0)
您在寻找策略模式吗?
答案 7 :(得分:0)
为什么不按如下方式对武器进行编码:
1 =电锯 2 =霰弹枪 4 =轨道枪
所以现在6的总和只能意味着角色拥有霰弹枪和铁轨枪。这是一个快速摘要,因此您不必遍历您的武器词典列表。你仍然需要一些结构来容纳武器,但至少你会通过这种方法获得速度。这预示着你可以只拥有每种类别的一种武器,但同时拥有多种类别。