伤害设计:视伤害为对象

前置文章:《游戏事件、效果模式设计》

大多数游戏中,伤害不仅仅是一个数值。MOBA 游戏中,存在物理伤害、法术伤害、真实伤害等;月圆之夜中,存在物理伤害、各种元素伤害、穿透伤害等。如果要实现上述功能,代码如下即可。

namespace DamageDesign
{
    public enum DamageType { Physics, Spell, Real, }
    public class Damage
    {
        public DamageType Type { get; set; }
        public int Value { get; set; }
    }
}

但伤害不仅存在类别差异,还可能有其他差异。

参考一个效果 “当受到伤害时,再次受到 1 点真实伤害”。如果不区分 “伤害” 的概念,这个效果则不可能存在,只能改成 “受到的伤害增加 1 点”。但这种情况下,如果存在 “元素免疫” 类似的效果,且原来受到的伤害为 “元素伤害” ,那么这个附加的 1 点伤害也无法造成。

有一种方案可以解决这个问题,添加属性 “附加伤害” 。“附加伤害” 不会触发 “伤害” 扳机,也就理所当然不会造成上面的死循环,同时也不会成为伤害计数器的目标。在这个动机下,我们可以考虑在伤害类里面集成 “附加伤害”。

namespace DamageDesign
{
    public enum DamageType { Physics, Spell, Real, }
    public class Damage
    {
        public DamageType Type { get; set; }
        public int Value { get; set; }
        public List<Damage> Attach { get; }
    }
}

附加伤害不单独触发事件,其只在 “伤害过滤器” 层级、生命值扣除层级进行结算。(一般来说,事件不应该关注附加伤害)

应用效果的设计模式一,伤害结算逻辑应该如下:

namespace DesignMode1_Damage_Ver
{
    public enum DamageType { Physics, Spell, Real, }
    public class Damage
    {
        public DamageType Type { get; set; }
        public int Value { get; set; }
        public List<Damage> Attach { get; }
        public Damage(DamageType type, int value)
        {
            Type = type;
            Value = value;
            Attach = new List<Damage>();
        }
    }
    public class BattleArgs
    {
        public Battle Battle { get; set; }
        public Character Raiser { get; set; } // Who Raise the Event.
    }
    public class DamageArgs : BattleArgs
    {
        public IDealDamage Source { get; set; }
        public IGetDamage Target { get; set; }
        public Damage Damage { get; set; }
    }
    public interface IGetDamageAction
    {
        bool HasGetDamage(DamageArgs args);
        void GetDamage(DamageArgs args);
    }
    public interface IGetDamageFilter
    {
        bool HasGetDamageFilter(DamageArgs damage);
        void GetDamageFilter(Damage damage);
    }
    public abstract class Buff
    {
        public abstract string Name { get; }
        public abstract string Description { get; }
        public abstract string Abstract { get; }
    }
    public class Character : IDealDamage, IGetDamage
    {
        public Battle Battle { get; }
        public List<Buff> Buffs { get; }
        public void GetDamage(IDealDamage source, Damage damage)
        {
            DamageArgs args = new DamageArgs()
            {
                Battle = Battle,
                Raiser = this,
                Source = source,
                Target = this,
                Damage = damage,
            };
            foreach (Buff b in Buffs)
                if (b is IGetDamageFilter filter && filter.HasGetDamageFilter(args))
                    filter.GetDamageFilter(damage);
            OnGetDamage(args);
            // Modify HP Here.
        }
        public void OnGetDamage(DamageArgs args)
        {
            foreach (Buff b in Buffs)
                if (b is IGetDamageAction ac && ac.HasGetDamage())
                    ac.GetDamage(args);
        }
    }
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值