[英]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.