首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >游戏被动技术体系

游戏被动技术体系
EN

Code Review用户
提问于 2014-02-20 09:24:12
回答 2查看 2.1K关注 0票数 7

我试图创建一些容易访问的不同技能的数据库。一般的想法是,每一项技能都应该做一些不同的事情,并能够对不同的事情采取行动(例如。一种技能是通过'x‘它对武器起作用的武器攻击,另一个是通过'z'% 它作用于怪物降低物品的机会的技能)。

我是这样看的:

  • 从任何地方都可以访问静态技能数据库。
  • 技能有影响(不同的返回类型、不同的参数和计算方法)
  • 为了使用技巧,我们在特定的计算中添加了它的效果;
    • 例句:如果我们想增加怪物的下降几率'z'%,那么,在计算掉几率的地方(在这个例子中是在monster类中),让我们假设(Monster.DropChance = 0.5f)我们添加技能效果:在技能实现之后(Monster.DropChance = 0.5f + SkillDatabase.IncreaseDropChance.Effect (这个))

我想出了一个这样的代码:公共静态类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)

嗯..。太可怕了。为了如此微小的效果而载入的文字。这是我第二次使用委托,第三次创建泛型类,我只是不知道用不同方法创建同一个类的其他解决方案。

伙计们,你们怎么解决这个问题?你知道如何维护有组织的、容易访问的技能数据库吗?或者这种方法一般都是错误的?

EN

回答 2

Code Review用户

发布于 2014-02-20 14:43:55

嗯,

嗯,我认为你的做法是正确的,虽然功能正确,但不能很好地扩展。

理想情况下,您希望尝试更多的聚合。从我的头顶上我会这样做:

代码语言:javascript
复制
interface Skill
{
   string Name{get;}
   double value{get;}
}

现在,使用这个基本对象,您可以编写剩下的代码,根据技能值进行计算。

至于修改,好吧,其他什么都不需要知道,如果一个技能被修改来使用它。要处理这个问题,我将从其他所有内容中选择ModifiedSkill不可知论者:

代码语言:javascript
复制
public interface ModifiedSkill : Skill
{
    IEnumerable<Modifier> Modifiers { get; }

    double BaseValue { get; }
    double Value { get; }

}

现在,你问的修饰语是什么?嗯:

代码语言:javascript
复制
public interface Modifier
{
    string Name { get; }
    string Cause { get; }
    double Apply(double skill);
    Boolean Active { get; set; }
}

因此,这就是您需要涵盖的所有可能发生的事件的所有接口,允许一些潜在的酷事情,比如时间修饰符或条件修饰符等等。

现在,如何实际实现这一点呢?

代码语言:javascript
复制
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。

票数 3
EN

Code Review用户

发布于 2014-02-20 16:18:02

考虑到@坎通-恩诺的S评论说我之前的建议不符合他的需要,我想我应该尝试另一种我正在玩的方法。

与上述不同,您可以使用一种加权计算器来尝试类似的方法,而不是实际的技能方法。

所以如果你有一个通用的

代码语言:javascript
复制
interface Modification
{
  int Weight {get;}
  double Calculate(double input);
}

并且有许多实现它的计算类,如IncreaseByXPercentCapAtMaximum或其他什么(更好的名称),您可以创建一个修饰符枚举,就像以前一样,使用一个具有简单函数的小工厂方法,它只向修饰符集合添加适当的类,然后根据权重和应用顺序进行计算。它的快照可能如下所示:

代码语言:javascript
复制
public interface SkillModifier
{
   void IncreaseByXPercent(int percent);
   void CapAtX(double value);

   double Calculate();

}

用法可能类似于:

代码语言:javascript
复制
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种用法的规则,因此这样做可能为时过早);但作为解决特定项目的问题,我将选择更直接的上述方法。

票数 2
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/42278

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档