责任链模式
让一群对象都有机会来处理一项请求,以减少请求发送者与接受者之间的耦合度。将所有的接收者对象串接起来,让请求沿着串接传递,知道有一个对象可以处理为止。
责任链模式的定义
参与者说明如下:
- 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);
}
}