c# - 如何设计具有多种技能的可扩展纸牌游戏

标签 c# unity3d

现在我想写一个类似中国游戏三国传奇的游戏。 玩家可以打出伤害对方的牌,举个简单的例子,如果你对敌人打出一张“杀”牌,如果敌人不打出“小姐”之类的牌,他就会失去生命点。 而如果我装备了一个名为“强化”的技能,它的作用是,如果你让敌人失去生命,你有一定的概率让敌人多失去一点生命, 如果我装备了一把名为“隆麟刀”的武器,它的功能是如果你用卡牌“杀死”让敌人失去生命,你可以选择移除敌人的两张牌而不是让他失去生命。 技能和武器有很多像上面两个,技能不是卡牌,和角色绑定(bind),武器和手牌一样,功能不同,大部分武器可以增加攻击距离。

我不确定你是否能理解游戏的玩法,更多细节你可以阅读wiki https://en.wikipedia.org/wiki/Legends_of_the_Three_Kingdoms .

我的问题是如何以可扩展的方式设计技能、武器和卡牌?

我的目标是让技能可以像武器一样被任何角色装备,随着时间的推移,我可以很容易地创造出很多新的技能和武器。

比如我想做一个新技能,它的作用是,如果你用卡牌“杀”让敌人失去1点生命值,那么你可以增加1点生命值。 我想做一个新技能,它的功能是如果我打出一张“小姐”牌,我可以获得一张新牌等等。

我对设计有一个简单的想法。 接口(interface):

public interface ICommonProperties
{
    string Name { get; set; }
    int AttackDistance { get; set; }
}
public interface ICommonEvents
{
    /// <summary>
    /// Before player plays card "Kill"
    /// </summary>
    void OnBeforeKill();

    /// <summary>
    /// After player plays card "Kill"
    /// </summary>
    void OnAfterKill();

    /// <summary>
    /// Before player plays card "Miss"
    /// </summary>
    void OnBeforeMiss();

    /// <summary>
    /// After player plays card "Miss"
    /// </summary>
    void OnAfterMiss();

    /// <summary>
    /// Trigger if lose life or increase life
    /// </summary>
    void OnLifeChange();

    /// <summary>
    /// Tigger if role is dying
    /// </summary>
    void OnDying();
}

public interface IRole : ICommonProperties, ICommonEvents
{
    int CurrentLife { get; set; }
    int MaxLife { get; set; }
    List<Card> CardsInHand { get; set; }
    List<IWeapon> BaseWeapons { get; set; }
    List<ISkill> BaseSkills { get; set; }
}

public interface IWeapon : ICommonProperties, ICommonEvents
{
    int AttackDistance { get; set; }
}

public interface ISkill : ICommonProperties, ICommonEvents
{

}

实现接口(interface):

public class BaseRole : IRole
    {
        public BaseRole()
        {
            this.CurrentLife = 3;
            this.MaxLife = 3;
            this.Name = "BaseRole";

        }

        #region Fileds
        public int CurrentLife
        {
            get;
            set;
        }

        public int MaxLife
        {
            get;
            set;
        }

        public string Name
        {
            get;
            set;
        }

        public List<Card> CardsInHand
        {
            get;
            set;
        }

        public List<IWeapon> BaseWeapons
        {
            get;
            set;
        }

        public List<ISkill> BaseSkills
        {
            get;
            set;
        }
        public int AttackDistance
        {
            get;
            set;
        }
        #endregion

        public virtual void OnBeforeKill()
        {

        }

        public virtual void OnAfterKill()
        {

        }

        public virtual void OnBeforeMiss()
        {
        }

        public virtual void OnAfterMiss()
        {
        }

        public virtual void OnLifeChange()
        {
        }

        public virtual void OnDying()
        {
            //If role is dying, he can ask medicine called "Yao" to gain one more life point.
        }



    }

    public class BaseWeapon : IWeapon
    {
        public BaseWeapon()
        {
            this.AttackDistance = 1;
            this.Name = "BaseWeapon";

        }
        public int AttackDistance
        {
            get;
            set;
        }

        public string Name
        {
            get;
            set;
        }

        public virtual void OnBeforeKill()
        {
        }

        public virtual void OnAfterKill()
        {
        }

        public virtual void OnBeforeMiss()
        {
        }

        public virtual void OnAfterMiss()
        {
        }

        public virtual void OnLifeChange()
        {
        }

        public virtual void OnDying()
        {
        }
    }

    public class BaseSkill : ISkill
    {
        public BaseSkill()
        {
            this.Name = "BaseSkill";
        }
        public string Name
        {
            get;
            set;
        }

        public int AttackDistance
        {
            get;
            set;
        }

        public virtual void OnBeforeKill()
        {
        }

        public virtual void OnAfterKill()
        {
        }

        public virtual void OnBeforeMiss()
        {
        }

        public virtual void OnAfterMiss()
        {
        }

        public virtual void OnLifeChange()
        {
        }

        public virtual void OnDying()
        {


        }
    }

    public class Card
    {
        public string Name { get; set; }
        public string Type { get; set; }

        /// <summary>
        /// Whether it can be used to attack others, such as "Kill" card CanAttack=true, card "Miss" CanAttack=false
        /// </summary>
        public bool CanAttack { get; set; }

    }

真实角色、武器和技能:

   public class XiangyuRole : BaseRole
        {
            public XiangyuRole()
            {
                this.Name = "Xiangyu";
                this.MaxLife = 4;
                this.CurrentLife = 4;
                // The role equip skill QinglingSkill by default.
                this.BaseSkills = new List<ISkill>();
                this.BaseSkills.Add(new QinglingSkill());

                this.BaseWeapons = new List<IWeapon>();
                this.BaseWeapons.Add(new RemoveCardsWeapon());
            }
        }

        public class RemoveCardsWeapon : BaseWeapon
        {
            public RemoveCardsWeapon()
            {
                this.Name = "RemoveCardsAfterWeapon";
                this.AttackDistance = 1;
            }

            public override void OnAfterKill()
            {
                //If you make the enemy lose life, you can remove two cards of the enemy instead of losing life.
            }
        }

        public class QinglingSkill : BaseSkill
        {
            public QinglingSkill()
            {
                this.Name = "GetACardAfterMiss";
            }

            public override void OnAfterMiss()
            {
                //if you play a "Miss" card, get a new card
            }
        }

我的问题

一个角色可以同时装备多个技能和不同的武器,打出一张卡牌可能会同时触发多个事件。 那么如何控制不同技能和武器提供的事件呢?它们可能是独占的也可能不是,如何控制事件的触发顺序? 有没有更好的方法来实现目标?

感谢您的回复。

最佳答案

我会使用更多的接口(interface)隔离。每个可能的事件一个接口(interface)(而不是 ICommonEvents 上的方法)。然后在“游戏”对象上使用发布-订阅来处理事件。让每张“卡片”收到所有事件的通知,但只处理它关心的事件。

关于c# - 如何设计具有多种技能的可扩展纸牌游戏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40148431/

相关文章:

C# Azure DeviceUpdateClient 403 禁止使用 ClientSecretCredential

c# - 如何识别重复的应用程序 list 证书

c# - 如何仅合并特定变更集 (TFS)

c# - Unity3d user32.dll 拖动窗口并取回焦点

c# - 设置数据库(SQLite)for Unity

c# - 在 Unity 编辑器中使用 AddComponent 脚本撤消移除游戏对象(播放模式)

c# - 水物理学。从哪儿开始?

c# - DLL Hell - 如果缺少 MySql.Data.dll 版本 6.9.3.0 或 6.8.3.0,我的应用程序将引发错误

c# - Unity3D 中的 Time.time vs DateTime.UtcNow.Millisecond 性能?

c# - "Remember Me"在服务器上不工作