返回

13.责任链模式

让一群对象都有机会来处理一项请求,以减少请求发送者与接受者之间的耦合度。将所有的接收者对象串接起来,让请求沿着串接传递,知道有一个对象可以处理为止。

责任链模式

让一群对象都有机会来处理一项请求,以减少请求发送者与接受者之间的耦合度。将所有的接收者对象串接起来,让请求沿着串接传递,知道有一个对象可以处理为止。

责任链模式的定义

参与者说明如下:

  • Handler(请求接收者接口)
    • 定义可以处理客户端请求事项的接口
    • 可以包含“可连接下一个同样能处理请求”的对象引用
  • Concretehandler1、Concretehandler2(实现请求接收者接口)
    • 实现请求处理接口,并普安段对象本身是否能处理这次请求
    • 不能完成请求的话,交由后继者(下一个)来处理
  • Client(请求发送者)
    • 将请求发送给第一个接收者,并等待请求的回复。

具体实现

    // 處理訊息的介面
    public abstract class Handler
    {
        protected Handler m_NextHandler = null;

        public Handler(Handler theNextHandler)
        {
            m_NextHandler = theNextHandler;
        }

        public virtual void HandleRequest(int Cost)
        {
            if (m_NextHandler != null)
                m_NextHandler.HandleRequest(Cost);
        }
    }

    // 處理所負責的訊息1
    public class ConcreteHandler1 : Handler
    {
        private int m_CostCheck = 10;

        public ConcreteHandler1(Handler theNextHandler) : base(theNextHandler)
        {
        }

        public override void HandleRequest(int Cost)
        {
            if (Cost <= m_CostCheck)
                Debug.Log("ConcreteHandler1.核準");
            else
                base.HandleRequest(Cost);
        }
    }

    // 處理所負責的訊息2
    public class ConcreteHandler2 : Handler
    {
        private int m_CostCheck = 20;

        public ConcreteHandler2(Handler theNextHandler) : base(theNextHandler)
        {
        }

        public override void HandleRequest(int Cost)
        {
            if (Cost <= m_CostCheck)
                Debug.Log("ConcreteHandler2.核準");
            else
                base.HandleRequest(Cost);
        }
    }

    // 處理所負責的訊息3
    public class ConcreteHandler3 : Handler
    {
        public ConcreteHandler3(Handler theNextHandler) : base(theNextHandler)
        {
        }

        public override void HandleRequest(int Cost)
        {
            Debug.Log("ConcreteHandler3.核準");
        }
    }

责任链模式的关卡系统

参与者说明如下:

  • IStageHandler:定义可以处理“过关判断”和“关卡开启”的接口,也包含指向下一个关卡对象的引用。
  • NormalStageHandler:实现关卡接口,负责“常规”关卡的开启和过关条件判断。
  • IStageScore:定义判断通关与否的操作接口。
  • StageScoreEnemyKilledCount:使用当前的“击杀角色数”,作为通关与否的判断。
  • IStageData:定义关卡内容的操作接口,关卡内容指的是:
    • 这一关会出现玩家玩家阵营的敌方角色数据的设置
    • 关卡开启
    • 关卡是否结束的判断
  • NormalStageData:实现“常规”关卡内容,实际将产生的敌方角色放入战场上攻击玩家阵营,以及实现判断关卡是否结束的方法

具体实现

// 關卡界面
public abstract class IStageHandler
{
	protected IStageHandler m_NextHandler = null;// 下一個關卡
	protected IStageData	m_StatgeData  = null;
	protected IStageScore   m_StageScore  = null;// 關卡的分數

	// 設定下一個關卡
	public IStageHandler SetNextHandler(IStageHandler NextHandler)
	{
		m_NextHandler = NextHandler;
		return m_NextHandler;
	}

	public abstract IStageHandler CheckStage();
	public abstract void Update();
	public abstract void Reset();
	public abstract bool IsFinished();
	public abstract int  LoseHeart();
}


// 一般關卡
public class NormalStageHandler : IStageHandler
{
    // 設定分數及關卡資料
    public NormalStageHandler(IStageScore StateScore, IStageData StageData)
    {
        m_StageScore = StateScore;
        m_StatgeData = StageData;
    }

    // 確認關卡
    public override IStageHandler CheckStage()
    {
        // 分數是否足夠
        if (m_StageScore.CheckScore() == false)
            return this;

        // 已經是最後一關了
        if (m_NextHandler == null)
            return this;

        // 確認下一個關卡
        return m_NextHandler.CheckStage();
    }

    public override void Update()
    {
        m_StatgeData.Update();
    }

    public override void Reset()
    {
        m_StatgeData.Reset();
    }

    public override bool IsFinished()
    {
        return m_StatgeData.IsFinished();
    }

    // 損失的生命值
    public override int LoseHeart()
    {
        return 1;
    }
}
// 關卡資訊介面
public abstract class IStageData
{
	public abstract void Update();
	public abstract	bool IsFinished();
	public abstract	void Reset();
}

// 一般關卡資訊
public class NormalStageData : IStageData
{
    private float m_CoolDown = 0; // 產生角色的間隔時間
    private float m_MaxCoolDown = 0; // 
    private Vector3 m_SpawnPosition = Vector3.zero; // 出生點
    private Vector3 m_AttackPosition = Vector3.zero; // 攻擊目標
    private bool m_AllEnemyBorn = false;

    //一般關卡要產生的敵人單位
    class StageData
    {
        public ENUM_Enemy emEnemy = ENUM_Enemy.Null;
        public ENUM_Weapon emWeapon = ENUM_Weapon.Null;
        public bool bBorn = false;

        public StageData(ENUM_Enemy emEnemy, ENUM_Weapon emWeapon)
        {
            this.emEnemy = emEnemy;
            this.emWeapon = emWeapon;
        }
    }

    // 關卡內要產生的敵人單位
    private List<StageData> m_StageData = new List<StageData>();

    // 設定多久產生一個敵方單位
    public NormalStageData(float CoolDown, Vector3 SpawnPosition, Vector3 AttackPosition)
    {
        m_MaxCoolDown = CoolDown;
        m_CoolDown = m_MaxCoolDown;
        m_SpawnPosition = SpawnPosition;
        m_AttackPosition = AttackPosition;
    }

    // 增加關卡的敵方單位
    public void AddStageData(ENUM_Enemy emEnemy, ENUM_Weapon emWeapon, int Count)
    {
        for (int i = 0; i < Count; ++i)
            m_StageData.Add(new StageData(emEnemy, emWeapon));
    }

    // 重置
    public override void Reset()
    {
        foreach (StageData pData in m_StageData)
            pData.bBorn = false;
        m_AllEnemyBorn = false;
    }

    // 更新
    public override void Update()
    {
        if (m_StageData.Count == 0)
            return;

        // 是否可以產生
        m_CoolDown -= Time.deltaTime;
        if (m_CoolDown > 0)
            return;
        m_CoolDown = m_MaxCoolDown;

        // 取得上場的角色
        StageData theNewEnemy = GetEnemy();
        if (theNewEnemy == null)
            return;

        // 一次產生一個單位
        ICharacterFactory Factory = PBDFactory.GetCharacterFactory();
        Factory.CreateEnemy(theNewEnemy.emEnemy, theNewEnemy.emWeapon, m_SpawnPosition, m_AttackPosition);
    }

    // 取得還沒產出
    private StageData GetEnemy()
    {
        foreach (StageData pData in m_StageData)
        {
            if (pData.bBorn == false)
            {
                pData.bBorn = true;
                return pData;
            }
        }

        m_AllEnemyBorn = true;
        return null;
    }

    // 是否完成
    public override bool IsFinished()
    {
        return m_AllEnemyBorn;
    }
}
// 關卡分數確認
public abstract class IStageScore 
{
	public abstract bool CheckScore();
}

// 關卡分數確認:敵人陣亡數
public class StageScoreEnemyKilledCount :  IStageScore
{
	private int m_EnemyKilledCount = 0;
	private StageSystem m_StageSystem = null;
	
	public StageScoreEnemyKilledCount( int KilledCount, StageSystem theStageSystem)
	{
		m_EnemyKilledCount = KilledCount;
		m_StageSystem = theStageSystem;
	}

	// 確認關卡分數是否達成
	public override bool CheckScore()
	{
		return ( m_StageSystem.GetEnemyKilledCount() >=  m_EnemyKilledCount);
	}
}