繁体   English   中英

OOP C#-MMO机械模拟器的设计模式

[英]OOP C# - Design pattern for MMO mechanics simulator

我一直在为FFXIV开发模拟器。

我一直很接近完成,然后陷入了一个对象访问问题,这个问题不允许我访问主玩家的统计信息。 我的项目可以在以下位置找到: https : //github.com/eein/chocobro

我知道我可以优化很多事情。 :P

基本上,我有点蛮力,让对象可以访问所需的对象,但是我正在寻找正确的方法来做事情。

我将开始重写它,所以不要太在意示例代码,但是在那里可以看到我遇到的问题。 :(

理想的下一次尝试是我要做的:从一个包含有关玩家对象的所有信息的玩家类开始(将来,我想为全组模拟创建多个)。

就像是:

int main(){
Player p = new Player();

public void setJob()
{
  if (job == "bard"){ Player p = new Bard(); }
  if (job == "warrior"){ Player p = new Warrior(); }
}

public class Player 
{
    private string name {get;set;}
    private string job {get;set;}
    private string STR;
    private string DEX;
    private string VIT; 
    //etc..

    public virtual void rotation()
    {
    }    
}

//I want to make the program a bit modular for jobs (roles/classes)
//So.. 

public class Bard : Player
{
    public override void rotation()
    {
        heavyshot.execute();    
        //etc.
    }

    Ability heavyshot = new Heavyshot();

    public class Heavyshot : Ability 
    {
        public Heavyshot() 
        {
            name = "Heavy Shot";
            potency = 150;
            dotPotency = 0;
            recastTime = 2.5;
            TPcost = 60;
            animationDelay = 0.8;
            abilityType = "Weaponskill";
            castTime = 0.0;
            duration = 0.0;
        }

        public override void impact() 
        {
            //add heavier shot buff activation here
            base.impact(); 
        }
    }
}

public class Ability{
public int cooldown;
public int cost;

public virtual void impact()
{
    public virtual void impact() 
    {
      //Deal some damage.
      // !! - the key problem is here, i want to initiate a roll to compare to the players CRIT rating versus the roll to determine the bonus damage. But I can't access the initiated players crit from here. The rating may change depending on abilities used so I can't create a new object. I know i need an object reference but I can't figure it out...
      log(time.ToString("F2") + " - " +  name + 
          " Deals " + potency + 
          " Potency Damage. Next ability at: " + nextability);
    }
}

我可能不太清楚,但是基本上我希望能够通过能力来访问玩家的爆击,并且我假设不能以这种方式设置能力以使其发挥作用。 有谁知道我应该使用哪种设计模式,以便功能中的虚拟功能可以访问父类玩家的统计信息?

理想情况下,我希望Bard类包含与Bard作业有关的所有能力和状态更新,一旦Bard继承了玩家并且该对象被更改为引用Bard对象,我如何使它成为由Ability类创建的能力就不要访问该函数时,需要在创建时引用父对象的对象引用。

我很困惑,但是非常感谢能理解我的胡言乱语并能提供帮助的人!

一种选择是将crit传递给Abillity的构造函数。

如果Ability始终与玩家连接,则为另一种选择。 将暴击属性与私有集一起公开:

public class Player 
{
    private double crit { get; private set;}
    ...
}

然后将Player传递给Ability的构造函数并保存在那里。 但是请注意,这会增加耦合

可以这样完成:

public class Ability
{
    protected Player _player;
    public Ability(Player player)
    {
        _player = player;
    }
}

您还想更改Ability派生的Headshot类

public class Headshot : Ability
{
    public Headshot(Player player) : base(player)
    {
        ...
    }
}

而不是直接执行能力轮换,而是将能力保存在列表中。 这样,您可以在Player中拥有设置方法,该方法将玩家轮流注入所有能力。 添加条件和某种否定下一个能力的“能力”,实际上是在某种列表中表达轮换的另一个原因。 因此,您不必到处重复“可使用的”检查,而只需将其放在一个位置即可。 像这样:

public class Player 
{
    private string name {get;set;}
    private string job {get;set;}
    private string STR;
    private string DEX;
    private string VIT; 
    //etc..

    public struct RotationAbility
    {
        public RotationAbility(Func<bool> cond, Ability ability)
        {
            this.cond = cond;
            this.ability = ability;
        }

        public Func<bool> cond;
        public Ability ability;
    }

    private List<RotationAbility> rotation = new List<RotationAbility>();

    public void execute()
    {
        foreach (var ab in rotation)
        {
            if (ab.cond())
                ab.ability.execute();
        }
    }

    public void setUpRotation()
    {
        setUpRotation(rotation);
        foreach (var ab in rotation)
        {
            ab.ability.Player = this;
        }
    }

    protected virtual void setUpRotation(List<RotationAbility> rotation) { }
}

//I want to make the program a bit modular for jobs (roles/classes)
//So.. 

public class Bard : Player
{
    protected override void setUpRotation(List<RotationAbility> rotation)
    {
        rotation.Add(new RotationAbility(()=>buff>0, new Heavyshot());
        //etc.
    }

    public class Heavyshot : Ability
    {
        public Heavyshot()
        {
            name = "Heavy Shot";
            potency = 150;
            dotPotency = 0;
            recastTime = 2.5;
            TPcost = 60;
            animationDelay = 0.8;
            abilityType = "Weaponskill";
            castTime = 0.0;
            duration = 0.0;
        }

        public override void impact()
        {
            //add heavier shot buff activation here
            base.impact();
        }
    }
}

    public class Ability{
        public Player Player { get; set; }

        public int cooldown;
        public int cost;
        public virtual void impact() 
        {
            //Deal some damage.
            // !! - the key problem is here, i want to initiate a roll to compare to the players CRIT rating versus the roll to determine the bonus damage. But I can't access the initiated players crit from here. The rating may change depending on abilities used so I can't create a new object. I know i need an object reference but I can't figure it out...
            log(time.ToString("F2") + " - " +  name + 
                " Deals " + potency + 
                " Potency Damage. Next ability at: " + nextability);
        }
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM