Closed. This question needs to be more focused。它当前不接受答案。












想要改善这个问题吗?更新问题,使其仅关注editing this post一个问题。

1年前关闭。



Improve this question




我正在创建一个角色扮演游戏,既有趣又学习。我正处于我的角色(巫师)施展咒语的地步。我正在使用一种策略模式来设置他们将要施放的咒语,然后再施放该咒语。我之所以采用这种方法,是因为我希望以后可以添加不同的拼写类型,而不必去搞砸角色/向导类。

我的问题-这是一个不良设计吗?是否有更好/更清洁/更简便的方法呢?

我试图远离成为试图使所有事物都适合设计模式的“那个家伙”。但是在这种情况下,我觉得这很合适。

到目前为止,这是我的代码中带有2个拼写的样子
public class Wizard : Creature
{
   public List<Spell> Spells { get; set; }

   public void Cast(Spell spell, Creature targetCreature)
   {
      spell.Cast(this, targetCreature);
   }
}

public abstract class Spell
{
   public string Name { get; set; }
   public int ManaCost { get; set; }
   public Spell(string name, int manaCost)
   {
      Name = name;
      ManaCost = manaCost;
   }
   public void Cast(Creature caster, Creature targetCreature)
   {
      caster.SubtractMana(ManaCost);
      ApplySpell(caster, targetCreature);
   }
   public abstract void ApplySpell(Creature caster, Creature targetCreature);
}

// increases the target's armor by 4
public class MageArmor : Spell
{
   public MageArmor() : base("Mage Armor", 4);
   public override void ApplySpell(caster, targetCreature)
   {
      targetCreature.AddAC(4);
   }
}

// target takes 7 damage
public class FireBall : Spell
{
   public FireBall() : base("Fire Ball", 5);
   public override void ApplySpell(caster, targetCreature)
   {
      targetCreature.SubtractHealth(7);
   }
}

现在来施放法术,我们做这样的事情:
Wizard wizard = new Wizard();
wizard.Cast(new Spell.MageArmor(), wizard); // i am buffing myself

更新:更新了代码,并提供了以下答案的一些建议

最佳答案

按照Willcodejavaforfood所说的,您可以设计一个SpellEffect类,该类描述您的咒语可能具有的单一效果。您可以创建一个“词汇表”来描述:

咒语的属性:

  • 名称
  • 法力消耗
  • 限制整个咒语(玩家,npc,怪物等)的目标限制
  • 法术总持续时间(SpellEffect持续时间的最高值)(10秒,5滴答声等)。
  • 转换时间
  • 法术距离(5米,65个单位,...)
  • 失败率(5%,90%)
  • 等待再次施放此法术之前的等待时间(重铸时间)
  • 等待再次施放任何咒语之前的等待时间(恢复时间)
  • 等...

  • SpellEffect的属性:
  • 效果类型(防御,进攻,buff,debuff等)
  • 效果的目标(自身,聚会,目标,目标周围的区域,目标线,...)
  • 效果所作用的属性或属性(hp,法力,最大hp,力量,攻击速度等)
  • 效果会改变多少状态(+10,-500,5%,...)
  • 效果持续多长时间(10秒,5个滴答声等)。
  • 等。

  • 我想您的词汇(上面括号中的词)将在一组枚举中定义。最好创建一个类层次结构来表示SpellEffect类型,而不是对该特定属性使用枚举,因为可能有一个SpellEffect类型不需要所有这些属性,或者可能存在某种自定义逻辑我没有考虑的每种基本SpellEffect类型。但这也可能使事情复杂化。 KISS原则=)。

    无论如何,关键是要把有关法术效果的特定信息提取到单独的数据结构中。这样做的好处是您可以创建1个Spell类,并使其包含SpellEffects列表以在激活时应用。然后,该法术可以在一击中执行多种功能(伤害敌人并治愈玩家,又称为生命抽头)。您为每个咒语创建一个新的Spell实例。当然,在某些时候,您将必须实际创建咒语。您可以轻松地将拼写编辑器实用程序组合在一起以使其变得更容易。

    此外,使用System.Xml.Serialization的XmlSerializer类,可以轻松地将您定义的每个SpellEffect 非常写入XML或从XML加载。在诸如SpellEffect之类的简单数据类上使用起来轻而易举。您甚至还可以将最终的Spell List序列化为xml。例如:
    <?xml header-blah-blah?>
    <Spells>
      <Spell Name="Light Healing" Restriction="Player" Cost="100" Duration="0s"
             CastTime="2s" Range="0" FailRate="5%" Recast="10s" Recovery="5s">
        <SpellEffect Type="Heal" Target="Self" Stat="Hp" Degree="500" Duration="0s"/>
      </Spell>
      <Spell Name="Steal Haste" Restriction="NPC" Cost="500" Duration="120s"
             CastTime="10s" Range="100" FailRate="10%" Recast="15s" Recovery="8s">
        <SpellEffect Type="Buff" Target="Self" Stat="AttackSpeed" Degree="20%" Duration="120s"/>
        <SpellEffect Type="Debuff" Target="Target" Stat="AttackSpeed" Degree="-20%" Duration="60s"/>
      </Spell>
      ...
    </Spells>
    

    您还可以选择将数据放在数据库而不是xml中。 Sqlite体积小,速度快,容易且免费。您还可以使用LINQ从xml或sqlite查询您的拼写数据。

    当然,您也可以为怪物做类似的事情,至少也可以为它们的数据做类似的事情。我不确定逻辑部分。

    如果您使用这种系统,则可以将Creature/Spell系统用于其他游戏,从而获得更多好处。如果您对拼写进行“硬编码”,则无法做到这一点。它还将允许您更改拼写(类平衡,错误等),而无需来重建和重新分发游戏可执行文件。只是一个简单的xml文件。

    天啊!现在,我为您的项目以及如何实现我所描述的项目感到非常兴奋。如果您需要任何帮助,请告诉我!!

    10-06 13:39