0

我一直在为 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);
    }
}

我可能不太清楚,但基本上我希望能够从技能中访问玩家的暴击,并且我假设技能不能以这种方式设置以使其发挥作用。有谁知道我应该使用什么样的设计模式,以便能力中的虚拟功能可以访问父类玩家的统计数据?

理想情况下,我希望吟游诗人类包含与吟游诗人工作有关的所有能力和统计更新,一旦吟游诗人继承了玩家并且对象被更改为引用吟游诗人对象,我该如何使它如此由能力类创建的能力不访问该函数时,需要在创建时对父对象进行对象引用。

我很困惑自己,但非常感谢任何理解我的胡言乱语并且可以提供帮助的人!

4

2 回答 2

1

一种选择是将 传递critAbillity的构造函数。

另一种选择,如果Ability始终连接到播放器。将暴击属性公有私有集:

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

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

这可以这样做:

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

您还想更改从 Ability 派生的 Headshot 类

public class Headshot : Ability
{
    public Headshot(Player player) : base(player)
    {
        ...
    }
}
于 2014-01-05T23:46:01.213 回答
0

不要直接执行技能轮换,而是将技能保存在列表中。这样,您可以在 Player 中使用 setup 方法,将玩家注入到轮换中的所有能力中。添加条件和某种“使用能力”,否定下一个能力实际上是在某种列表中表达轮换的另一个理由。因此,您不必在任何地方都重复“使用能力”检查,而是将它放在一个地方。像这样的东西:

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);
        }
    }
}
于 2014-01-05T23:42:15.040 回答