我试图创建一些容易访问的不同技能的数据库。一般的想法是,每一项技能都应该做一些不同的事情,并能够对不同的事情采取行动(例如。一种技能是通过'x‘它对武器起作用的武器攻击,另一个是通过'z'% 它作用于怪物降低物品的机会的技能)。
我是这样看的:
我想出了一个这样的代码:公共静态类SkillData //静态类作为数据库,用于将技能保存在一个位置{ //技能公共枚举名称{ IncreaseDropChance = 1,IncreaseWeaponAtk =2} // T-技能效果的返回类型,效果工作的对象的U类型公共类Skill {公共int级{ get;set;} public浮点ExperienceCost { get;set;公共名称SName;//委托为每个技能公共委托T EffectDel (U OnWhat)创建独特的效果;公共EffectDel效果;公共技能(名称){ SName = name;} //自定义字典,用于通用技能公共类SkillDictionary {私有Dictionary _dict =新Dictionary();公共无效Add (名称密钥,Skill技能){_dict.Add(密钥,技能);} public Skill GetValue(名称密钥){返回_dict钥匙 as Skill;}/ static以便于访问公共静态SkillDictionary DB =新SkillDictionary ();静态SkillData () { //这里我想一个接一个地创建技能,并将它们添加到DB /,这是技能创建技能< float,Player> IncrWpnAtk = new Skill (SName.IncreaseWeaponAtk);IncrWpnAtk.Level = 5;//假设我们要将武器攻击增加100% * skillLvl IncrWpnAtk.Effect = (player) => {float additionalAtk = player.Eq.Weapon.Atk * IncrWpnAtk.Level;返回additionalAtk;};DB.Add (Name.IncreaseWeaponAtk,IncrWpnAtk);}
在武器攻击计算中,我们加入了SkillData.DB.GetValue<float, Player> (IncreaseWeaponAtk).Effect (player)。
嗯..。太可怕了。为了如此微小的效果而载入的文字。这是我第二次使用委托,第三次创建泛型类,我只是不知道用不同方法创建同一个类的其他解决方案。
伙计们,你们怎么解决这个问题?你知道如何维护有组织的、容易访问的技能数据库吗?或者这种方法一般都是错误的?
发布于 2014-02-20 14:43:55
嗯,
嗯,我认为你的做法是正确的,虽然功能正确,但不能很好地扩展。
理想情况下,您希望尝试更多的聚合。从我的头顶上我会这样做:
interface Skill
{
string Name{get;}
double value{get;}
}现在,使用这个基本对象,您可以编写剩下的代码,根据技能值进行计算。
至于修改,好吧,其他什么都不需要知道,如果一个技能被修改来使用它。要处理这个问题,我将从其他所有内容中选择ModifiedSkill不可知论者:
public interface ModifiedSkill : Skill
{
IEnumerable<Modifier> Modifiers { get; }
double BaseValue { get; }
double Value { get; }
}现在,你问的修饰语是什么?嗯:
public interface Modifier
{
string Name { get; }
string Cause { get; }
double Apply(double skill);
Boolean Active { get; set; }
}因此,这就是您需要涵盖的所有可能发生的事件的所有接口,允许一些潜在的酷事情,比如时间修饰符或条件修饰符等等。
现在,如何实际实现这一点呢?
Public class ModifiedSkillImpl : ModifiedSkill
{
private readonly List<Modifier> _modifiers;
private readonly double _baseValue;
public ModifiedSkillImpl(string name, double baseValue, IEnumerable<Modifier> modifiers)
{
if (name == null) throw new ArgumentNullException("name");
if (modifiers == null) throw new ArgumentNullException("modifiers");
Name = name;
_baseValue = baseValue;
_modifiers = modifiers.ToList();
}
public string Name { get; private set; }
public IEnumerable<Modifier> Modifiers
{
get
{
return _modifiers;
}
}
public double BaseValue
{
get
{
return _baseValue;
}
}
public double Value
{
get
{
return Modifiers.Aggregate(_baseValue, (current, modifier) => modifier.Apply(current));
}
}
}现在,这只是一个例子,当然,您可以执行许多其他技能实现。最后一步是创建PoisonModifier/ItchyLeftEarModifier等,然后应用它们,比如+5% -20%等。
这种分离还意味着,虽然大多数东西将使用Skill.Value,在修改技能的情况下,修改后的技能将是修改后的版本,但是一些特殊的东西可以检查该技能是否是修改后的技能,如果是这样的话,那么就使用基本属性吧!
(最后一点)我对ModifiedSkillImpl中的值聚合有点浪费,tbh可能有一个私有变量用于修改技能,并且只有在上次调用后修改了修饰符时才重新计算,但您知道,这只是一个快速的POC。
发布于 2014-02-20 16:18:02
考虑到@坎通-恩诺的S评论说我之前的建议不符合他的需要,我想我应该尝试另一种我正在玩的方法。
与上述不同,您可以使用一种加权计算器来尝试类似的方法,而不是实际的技能方法。
所以如果你有一个通用的
interface Modification
{
int Weight {get;}
double Calculate(double input);
}并且有许多实现它的计算类,如IncreaseByXPercent或CapAtMaximum或其他什么(更好的名称),您可以创建一个修饰符枚举,就像以前一样,使用一个具有简单函数的小工厂方法,它只向修饰符集合添加适当的类,然后根据权重和应用顺序进行计算。它的快照可能如下所示:
public interface SkillModifier
{
void IncreaseByXPercent(int percent);
void CapAtX(double value);
double Calculate();
}用法可能类似于:
Skill health = new SkillImpl(100);
health.Modify.IncreateByXPercent(5);
health.Modify.CapAt(5000);
PrintTheValue(health.Value);因此,修改访问器是SkillModifier类的复合实例,它将Modification实例添加到内部枚举中,并按权重排序。
技能类Skill.Value调用它的复合Modify.Calculate(_baseValue)或其他东西,仍然返回合并的结果,并且所有的结果都被安全封装。
就我个人而言,我不那么倾向于这样做,在为您的方程聚合构建一个流畅的界面方面,开销更大,对于新的人来说,更难掌握它的使用,但是,不管您的能力如何,它的乍一看都比任何其他解决方案都读得更好。
因此,如果您要自己将其打包为一个修饰符API,这可能是可行的方法(但对于api添加,我倾向于遵循3种用法的规则,因此这样做可能为时过早);但作为解决特定项目的问题,我将选择更直接的上述方法。
https://codereview.stackexchange.com/questions/42278
复制相似问题