(十五)责任链模式(关卡系统)
责任链模式的代码实现:
public class ChainOfResponsibilityDM : MonoBehaviour
{
private void Start()
{
char c = 'b';
HandlerA handlerA = new HandlerA();
HandlerB handlerB = new HandlerB();
HandlerC handlerC = new HandlerC();
handlerA.SetNextHandle(handlerB).SetNextHandle(handlerC);
handlerA.Handler(c);
}
}
public abstract class IDMHandler
{
protected IDMHandler mNextHandler;
public IDMHandler NextHandler
{
set { mNextHandler = value; }
}
public IDMHandler SetNextHandle(IDMHandler iDMHandle)
{
mNextHandler = iDMHandle;
return mNextHandler;
}
public virtual void Handler(char c) { }
}
public class HandlerA : IDMHandler
{
public override void Handler(char c)
{
if (c == 'a')
Debug.Log("处理了当前的问题:" + c);
else {
if (mNextHandler != null)
{
mNextHandler.Handler(c);
}
}
}
}
public class HandlerB: IDMHandler
{
public override void Handler(char c)
{
if (c == 'b')
Debug.Log("处理了当前的问题:" + c);
else
{
if (mNextHandler != null)
{
mNextHandler.Handler(c);
}
}
}
}
public class HandlerC: IDMHandler
{
public override void Handler(char c)
{
if (c == 'c')
Debug.Log("处理了当前的问题:" + c);
else
{
if (mNextHandler != null)
{
mNextHandler.Handler(c);
}
}
}
}
开发关卡Handler对应每一关的游戏逻辑
public class IStageHandler : MonoBehaviour
{
public int mStageLV;
/// <summary>
/// 通过敌人被杀死的数量来判断是否进入下一个关卡
/// </summary>
private int mCountToFinish;
protected StageSystem mStageSystem;
protected IStageHandler mNextHandler;
/// <summary>
/// 设置责任链
/// </summary>
/// <returns></returns>
public IStageHandler SetNextHandler(IStageHandler stageHandler)
{
mNextHandler = stageHandler;
return mNextHandler;
}
public IStageHandler(StageSystem stageSystem, int stageLV, int countToFinish)
{
mStageSystem = stageSystem;
mStageLV = stageLV;
mCountToFinish = countToFinish;
}
//处理方法
public void Handler(int StageLV)
{
if (mStageLV == StageLV)
{
UpdateStage();
ChectStageIsFinished();
}
else
{
mNextHandler.Handler(StageLV);
}
}
/// <summary>
/// 实时更新关卡
/// </summary>
protected virtual void UpdateStage()
{
//TODO
}
//检查关卡是否结束
public void ChectStageIsFinished()
{
if (mStageSystem.GetCountOfEnemyKilled() >= mCountToFinish)
{
mStageSystem.EnterNextStage();
}
}
}
public class NormalStageHandler : IStageHandler {
private EnemyType mEnemyType;
private WeaponType mWeaponType;
private Vector3 mSpawnPos;
private int mEnemyCount;
public NormalStageHandler(StageSystem stageSystem, int stageLV, int countToFinish, EnemyType enemyType, WeaponType weaponType, Vector3 spawnPos, int enemyCount)
: base(stageSystem, stageLV, countToFinish)
{
mEnemyType = enemyType;
mWeaponType = weaponType;
mSpawnPos = spawnPos;
mEnemyCount = enemyCount;
}
protected override void UpdateStage()
{
base.UpdateStage();
}
}
public class StageSystem : IGameSystem
{
//得到敌人死亡的数量
public int GetCountOfEnemyKilled()
{
//TODO
return 0;
}
//进入下一个关卡的方法
public void EnterNextStage()
{
//TODO
}
}
开发关卡内敌人的生成 :
在UpdateStage中判断 当敌人数量小于关卡敌人需要生成的数量时,计时器开启,生成对应的敌人并让生成敌人的数量mCountSpawned自增,生成后需重置计时器;
public class NormalStageHandler : IStageHandler {
private EnemyType mEnemyType;
private WeaponType mWeaponType;
private Vector3 mSpawnPos;
private int mEnemyCount; //敌人的数量
private int mEnemySpawnTime = 1 ; //敌人生成间隔
private float mEnemySpawnTimer = 0; //敌人生成间隔计时器
private int mCountSpawned = 0;//记录敌人生成的数量
public NormalStageHandler(StageSystem stageSystem, int stageLV, int countToFinish, EnemyType enemyType, WeaponType weaponType, Vector3 spawnPos, int enemyCount)
: base(stageSystem, stageLV, countToFinish)
{
mEnemyType = enemyType;
mWeaponType = weaponType;
mSpawnPos = spawnPos;
mEnemyCount = enemyCount;
mEnemySpawnTimer = mEnemySpawnTime;
}
protected override void UpdateStage()
{
base.UpdateStage();
if (mEnemyCount < mCountSpawned)
{
mEnemySpawnTimer -= Time.deltaTime;
if (mEnemySpawnTimer <= 0)
{
SpawnEnemy();
mEnemySpawnTimer = mEnemySpawnTime;
}
}
}
public void SpawnEnemy()
{
mCountSpawned++;
switch (mEnemyType)
{
case EnemyType.Elf:
FactoryManager.enemyFactory.CreateCharacter<EnemyElf>(mWeaponType, mSpawnPos);
break;
case EnemyType.Troll:
FactoryManager.enemyFactory.CreateCharacter<EnemyTroll>(mWeaponType, mSpawnPos);
break;
case EnemyType.Ogre:
FactoryManager.enemyFactory.CreateCharacter<EnemyOgre>(mWeaponType, mSpawnPos);
break;
default:
Debug.LogWarning("无法生成敌人,类型为"+mEnemyType);
break;
}
}
}
构造关卡的责任链
在重写的Init()初始化方法中,初始化关卡的责任链并声明一个IStageHandler mRootHandler在责任链后令
mRootHandler = Hnadler1 并在重写的update方法中更新 mRootHandler.Handler(mLV); 即实时更新当前关卡是否等于mLV
public class StageSystem : IGameSystem
{
int mLV = 1; //初始等级
List<Vector3> mEnemySpawnPosList;
private IStageHandler mRootHandler;
public override void Init()
{
base.Init();
InitPos();
InitStageChain();
}
public override void Update()
{
base.Update();
mRootHandler.Handler(mLV);
}
//初始化敌人的出生位置
private void InitPos()
{
mEnemySpawnPosList = new List<Vector3>();
int i = 1;
while (true)
{
GameObject go = GameObject.Find("Position"+i);
if (go != null)
{
mEnemySpawnPosList.Add(go.transform.position);
go.SetActive(false);
i++;
}
else
break;
}
}
private Vector3 GetEnemyRandomSpawnPos()
{
return mEnemySpawnPosList[Random.Range(0, mEnemySpawnPosList.Count)];
}
//初始化关卡的责任链
private void InitStageChain()
{
int lv = 1;
NormalStageHandler handler1 = new NormalStageHandler(this, lv++, 3,EnemyType.Elf,WeaponType.Gun, GetEnemyRandomSpawnPos(),3);
NormalStageHandler handler2 = new NormalStageHandler(this, lv++, 6, EnemyType.Elf, WeaponType.Rifle, GetEnemyRandomSpawnPos(), 3);
NormalStageHandler handler3 = new NormalStageHandler(this, lv++, 9, EnemyType.Elf, WeaponType.Rocket, GetEnemyRandomSpawnPos(), 3);
NormalStageHandler handler4 = new NormalStageHandler(this, lv++, 13, EnemyType.Ogre, WeaponType.Gun, GetEnemyRandomSpawnPos(), 4);
NormalStageHandler handler5 = new NormalStageHandler(this, lv++, 17, EnemyType.Ogre, WeaponType.Rifle, GetEnemyRandomSpawnPos(), 4);
NormalStageHandler handler6 = new NormalStageHandler(this, lv++, 21, EnemyType.Ogre, WeaponType.Rocket, GetEnemyRandomSpawnPos(), 4);
NormalStageHandler handler7 = new NormalStageHandler(this, lv++, 26, EnemyType.Troll, WeaponType.Gun, GetEnemyRandomSpawnPos(), 5);
NormalStageHandler handler8 = new NormalStageHandler(this, lv++, 31, EnemyType.Troll, WeaponType.Rifle, GetEnemyRandomSpawnPos(), 5);
NormalStageHandler handler9 = new NormalStageHandler(this, lv++, 36, EnemyType.Troll, WeaponType.Rocket, GetEnemyRandomSpawnPos(), 5);
//设置责任链
handler1.SetNextHandler(handler2).
SetNextHandler(handler3).
SetNextHandler(handler4).
SetNextHandler(handler5).
SetNextHandler(handler6).
SetNextHandler(handler7).
SetNextHandler(handler8).
SetNextHandler(handler9);
mRootHandler = handler1;
}
//得到敌人死亡的数量
public int GetCountOfEnemyKilled()
{
//TODO
return 0;
}
//进入下一个关卡的方法
public void EnterNextStage()
{
//TODO
mLV++;
}
}
完善当没敌人时去基地:
在StageSystem中声明变量Vector3 mTargetPos; 并可get访问,在GameFacade中完善GetEnemyTargetPosition()方法,使敌人在没有目标(我方士兵)时向基地位置移动
StageSystem :
private Vector3 mTargetPos;
public Vector3 TargetPos { get { return mTargetPos; } }
GameFacade:
/// <summary>
/// 用于得到敌人的位置
/// </summary>
public Vector3 GetEnemyTargetPosition()
{
return stageSystem.TargetPos;
}
处理角色的死亡和移除
在ICharacter中声明 mIsKilled 是否死亡, mCanDestroy是否可以销毁角色 ,mKilledTimer 角色死亡销毁延迟时间
重写Killed 角色死亡方法,并写入Release 方法用于销毁角色,在Update中更新 角色是否死亡,若死亡mIsKilled设置为true
死亡计时器mKilledTimer 开始递减至0,将mCanDestroy设置为true(死亡判断在UnderAttck的子类重写中)
角色死亡后,状态机不更新,在ISoldier和IEnemy的UpdateFSMAI中加入 if (mIsKilled) return;
在CharacterSystem的Update方法中写入RemoveIsKilledChara(List<ICharacter> CharacterList)方法用于将
传入的角色集合中CanDestroy的角色 放入一个临时集合中并调用其Release()方法销毁角色,并将其从传入的集合中Remove()
public abstract class ICharacter
{
protected GameObject mGameObject;//游戏角色
protected NavMeshAgent mNavMeshAgent;
protected AudioSource mAudioSource;
protected ICharacterAttr mCharacterAttri;//角色属性
protected Animation mAnimation;//角色动画
protected IWeapon mWeapon;
protected bool mIsKilled = false;
protected bool mCanDestroy = false;
public bool CanDestroy { get { return mCanDestroy; } }
private float mKilledTimer = 2; //角色死亡后延迟2秒进行动画特效等的播放
public IWeapon Weapon
{
set
{
mWeapon = value;
mWeapon.Owner = this;
//找到放置武器的位置
GameObject child = UnityTools.FindChild(mGameObject, "weapon-point");
//给武器设置父亲
UnityTools.Attach(child, mWeapon.gameObject);
}
}
public ICharacterAttr CharacterAttri { set { mCharacterAttri = value; } get { return mCharacterAttri; } }
public float mAtkRange { get { return mWeapon.AtkRange; } } //武器的攻击距离
public GameObject gameObject
{
get { return mGameObject; }
set
{
mGameObject = value;
mNavMeshAgent = mGameObject.GetComponent<NavMeshAgent>();
mAudioSource = mGameObject.GetComponent<AudioSource>();
mAnimation = mGameObject.GetComponentInChildren<Animation>();
}
}
/// <summary>
/// 释放资源销毁游戏物体,对应的属性都会销毁,Destroy角色
/// </summary>
public void Release()
{
GameObject.Destroy(mGameObject);
}
public void Update()
{
if (mIsKilled)
{
mKilledTimer -= Time.deltaTime;
if (mKilledTimer <= 0)
mCanDestroy = true;
return;
}
mWeapon.Update();
}
public abstract void UpdateFSMAI(List<ICharacter> targets);
public void Attack(ICharacter target)
{
mWeapon.Fire(target.GetPosition);
mGameObject.transform.LookAt(target.GetPosition);
mAnimation.Play("attack");
target.UnderAttck((int)mWeapon.Atk+mCharacterAttri.CritValue);
}
/// <summary>
/// 受到伤害后执行的方法
/// </summary>
/// <param name="damage">受到的伤害</param>
public virtual void UnderAttck(int damage)
{
//被攻击的特效 (只有敌人有)
//死亡的动画、音频 (只有战士有)
mCharacterAttri.TakeDamege(damage);
}
/// <summary>
/// 角色死亡后执行的方法
/// </summary>
protected void Killed()
{
mIsKilled = true;
mNavMeshAgent.Stop();
}
/// <summary>
/// 得到角色位置
/// </summary>
/// <returns></returns>
public Vector3 GetPosition
{
get
{
if (mGameObject == null)
{
Debug.LogWarning("mGameObject为空");
return Vector3.zero;
}
return mGameObject.transform.position;
}
}
/// <summary>
/// 设置角色动画
/// </summary>
/// <param name="animName"></param>
public void SetAnimation(string animName)
{
mAnimation.CrossFade(animName);
}
/// <summary>
/// 追击状态下,移动至目标
/// </summary>
/// <param name="target"></param>
public void MoveToTarget(Vector3 target)
{
mNavMeshAgent.SetDestination(target);
mAnimation.Play("move");
}
protected void DoPlayEffect(string effectName)
{
//加载特效
GameObject effectGO = FactoryManager.assetFactory.LoadEffect(effectName);
effectGO.transform.position = GetPosition;
//控制销毁 -- 在特效自身 加一个 类似计时器的脚本进行销毁。
effectGO.AddComponent<DestroyEffect>();
}
protected void DoPlaySound(string clipName)
{
AudioClip clip = FactoryManager.assetFactory.LoadAudioClip(clipName);
mAudioSource.clip = clip;
mAudioSource.Play();
}
}
public class CharacterSystem : IGameSystem
{
private List<ICharacter> EnemyList = new List<ICharacter>();
private List<ICharacter> SoldierList = new List<ICharacter>();
public void AddEnemy(IEnemy enemy)
{
//if (enemy == null) return;
EnemyList.Add(enemy);
}
public void RemoveEnemy(IEnemy enemy)
{
//if (enemy == null) return;
EnemyList.Remove(enemy);
}
public void AddSoldier(ISoldier soldier)
{
//if (enemy == null) return;
SoldierList.Add(soldier);
}
public void RemoveSoldier(ISoldier soldier)
{
//if (enemy == null) return;
SoldierList.Remove(soldier);
}
public override void Update()
{
RemoveIsKilledChara(EnemyList);
RemoveIsKilledChara(SoldierList);
foreach (ISoldier soldier in SoldierList)
{
soldier.Update();
soldier.UpdateFSMAI(EnemyList);
}
foreach (IEnemy enemy in EnemyList)
{
enemy.Update();
enemy.UpdateFSMAI(SoldierList);
}
}
public void RemoveIsKilledChara(List<ICharacter> CharacterList)
{
List<ICharacter> IsKilledCharaList = new List<ICharacter>();
foreach (ICharacter character in CharacterList)
{
if (character.CanDestroy)
{
IsKilledCharaList.Add(character);
}
}
foreach (ICharacter c in IsKilledCharaList)
{
CharacterList.Remove(c);
c.Release();
}
}
}
ISoldier:
public override void UpdateFSMAI(List<ICharacter> targets)
{
if (mIsKilled) return;
mSoldierFSMSystem.CurrentState.Act(targets);
mSoldierFSMSystem.CurrentState.Reason(targets);
}
IEnemy:
public override void UpdateFSMAI(List<ICharacter> targets)
{
if (mIsKilled) return;
fsm.CurrentState.Reason(targets);
fsm.CurrentState.Act(targets);
}
(十六)观察者模式
观察者模式代码实现:
public class ObserverDM : MonoBehaviour
{
private void Start()
{
ConcreteSubject1 sub1 = new ConcreteSubject1();
ConcreteObserver1 obs1 = new ConcreteObserver1(sub1);
sub1.RegisterObserver(obs1);
sub1.Message = "新的信息";
}
}
public abstract class Subject
{
List<Observer> mObserverList = new List<Observer>();
public void RegisterObserver(Observer obs)
{
mObserverList.Add(obs);
}
public void RemoveObserver(Observer obs)
{
mObserverList.Remove(obs);
}
public void NotifyObserver()
{
foreach (Observer obs in mObserverList)
{
obs.Update();
}
}
}
public class ConcreteSubject1 : Subject
{
private string mMessage;
public string Message
{
set
{
mMessage = value;
NotifyObserver();
}
get { return mMessage; }
}
}
public abstract class Observer
{
public abstract void Update();
}
public class ConcreteObserver1 : Observer
{
private ConcreteSubject1 mSub;
public ConcreteObserver1(ConcreteSubject1 subject)
{
mSub = subject;
}
public override void Update()
{
Debug.Log("Oberser1更新显示" + mSub.Message);
}
}
开发事件的主题类:
创建事件主题和事件观察者的基类,再开发 士兵死亡主题事件,敌人死亡主题事件,关卡等级主题事件
public class IGameEventSubject
{
private List<IGameEventObserver> ObserverList = new List<IGameEventObserver>();
//注册观察者
public void RegisterObserver(IGameEventObserver obs)
{
ObserverList.Add(obs);
}
//移除观察者
public void RemoveObserver(IGameEventObserver obs)
{
ObserverList.Remove(obs);
}
通知观察者
public virtual void NotifyObserver()
{
foreach (IGameEventObserver obs in ObserverList)
{
obs.Updates();
}
}
}
public abstract class IGameEventObserver
{
public abstract void Updates();
public abstract void SetSubject(IGameEventSubject sub);
}
public class NewStageSubject : IGameEventSubject
{
private int mCurrentStage;
private int CurrentStage { get { return mCurrentStage; } }
public override void NotifyObserver()
{
mCurrentStage++;
base.NotifyObserver();
}
}
public class SoldierKilledSubject : IGameEventSubject
{
private int mSoldierKilled;
private int SoldierKilled { get { return mSoldierKilled; } }
public override void NotifyObserver()
{
mSoldierKilled++;
base.NotifyObserver();
}
}
public class EnemyKilledSubject : IGameEventSubject
{
private int mEnemyKilled;
private int EnemyKilled { get { return mEnemyKilled; } }
public override void NotifyObserver()
{
mEnemyKilled++;
base.NotifyObserver();
}
}
开发游戏事件系统管理所有的事件主题类 :
声明枚举类事件类型来区分事件,再用字典存所有的主题类
public enum GameEventType
{
Null,
EnemyKilled,
SoldierKilled,
NewStage
}
public class GameEventSystem : IGameSystem
{
private Dictionary<GameEventType, IGameEventSubject> mGameEventDict = new Dictionary<GameEventType, IGameEventSubject>();
public override void Init()
{
base.Init();
InitGameEvents();
}
//初始化字典
private void InitGameEventDict()
{
mGameEventDict.Add(GameEventType.EnemyKilled, new EnemyKilledSubject());
mGameEventDict.Add(GameEventType.SoldierKilled, new SoldierKilledSubject());
mGameEventDict.Add(GameEventType.NewStage, new NewStageSubject());
}
public void RegisterObserver(GameEventType eventType, IGameEventObserver obs)
{
//if (mGameEventDict.ContainsKey(eventType) == false)
//{
// Debug.Log("没有对应的事件类型" + eventType + "的主题类"); return;
//}
//IGameEventSubject sub = mGameEventDict[eventType];
IGameEventSubject sub = GetGameEvent(eventType);
if (sub == null) return;
sub.RegisterObserver(obs);
obs.SetSubject(sub);
}
public void RemoveObserver(GameEventType eventType, IGameEventObserver obs)
{
//if (mGameEventDict.ContainsKey(eventType) == false)
//{
// Debug.Log("没有对应的事件类型" + eventType + "的主题类"); return;
//}
//IGameEventSubject sub = mGameEventDict[eventType];
IGameEventSubject sub = GetGameEvent(eventType);
if (sub == null) return;
sub.RemoveObserver(obs);
obs.SetSubject(null);
}
public void NotifyObserver(GameEventType eventType)
{
//if (mGameEventDict.ContainsKey(eventType) == false)
//{
// Debug.Log("没有对应的事件类型" + eventType + "的主题类"); return;
//}
//IGameEventSubject sub = mGameEventDict[eventType];
IGameEventSubject sub = GetGameEvent(eventType);
if (sub == null) return;
sub.NotifyObserver();
}
private IGameEventSubject GetGameEvent(GameEventType eventType)
{
if (mGameEventDict.ContainsKey(eventType) == false)
{
Debug.Log("没有对应的事件类型" + eventType + "的主题类"); return null;
}
IGameEventSubject sub = mGameEventDict[eventType];
return sub;
}
}
开发敌人死亡事件的触发和监听 :
删除GameEventSystem中Init()初始化字典方法,在GetGameEvent中获取,避免初始化时字典未初始化完成,别的地方无法调用
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public enum GameEventType
{
Null,
EnemyKilled,
SoldierKilled,
NewStage
}
public class GameEventSystem : IGameSystem
{
private Dictionary<GameEventType, IGameEventSubject> mGameEventDict = new Dictionary<GameEventType, IGameEventSubject>();
public override void Init()
{
base.Init();
}
public void RegisterObserver(GameEventType eventType, IGameEventObserver obs)
{
IGameEventSubject sub = GetGameEvent(eventType);
if (sub == null) return;
sub.RegisterObserver(obs);
obs.SetSubject(sub);
}
public void RemoveObserver(GameEventType eventType, IGameEventObserver obs)
{
IGameEventSubject sub = GetGameEvent(eventType);
if (sub == null) return;
sub.RemoveObserver(obs);
obs.SetSubject(null);
}
public void NotifyObserver(GameEventType eventType)
{
IGameEventSubject sub = GetGameEvent(eventType);
if (sub == null) return;
sub.NotifyObserver();
}
private IGameEventSubject GetGameEvent(GameEventType eventType)
{
if (mGameEventDict.ContainsKey(eventType) == false)
{
switch (eventType)
{
case GameEventType.EnemyKilled:
mGameEventDict.Add(GameEventType.EnemyKilled, new EnemyKilledSubject());
break;
case GameEventType.SoldierKilled:
mGameEventDict.Add(GameEventType.SoldierKilled, new SoldierKilledSubject());
break;
case GameEventType.NewStage:
mGameEventDict.Add(GameEventType.NewStage, new NewStageSubject());
break;
default:
Debug.LogWarning("没有对应的事件类型" + eventType + "的主题类");
return null;
}
}
IGameEventSubject sub = mGameEventDict[eventType];
return sub;
}
}
在StageSystem中声明mCountOfEnemyKilled(敌人死亡的数量),并设置set方法。
在EnemyKilledObserverStageSystem的update中将EnemyKilledSubject(通过SetSubject方法赋值,即注册时就赋值了)的EnemyKilled赋值给StageSystem的mCountOfEnemyKilled
StageSystem的Init()中对敌人死亡事件GameEventType.EnemyKilled 进行了注册监听,
观察者为EnemyKilledObserverStageSystem。
当角色死亡时,IEnemy的Killed()通知监听敌人死亡(GameEventType.EnemyKilled)事件的观察者,调用所有观察者的update方法,即EnemyKilledSubject中Update方法使EnemyKilled ++,然后再EnemyKilledObserverStageSystem的update中将其赋值给StageSystem的mCountOfEnemyKilled,从而使敌人死亡数量+1
public class StageSystem : IGameSystem
{
int mLV = 1; //初始等级
List<Vector3> mEnemySpawnPosList;
private IStageHandler mRootHandler;
private int mCountOfEnemyKilled = 0; //敌人死亡的数量
private Vector3 mTargetPos;
public Vector3 TargetPos { get { return mTargetPos; } }
public int CountOfEnemyKilled { set { mCountOfEnemyKilled = value; } }
public override void Init()
{
base.Init();
InitPos();
InitStageChain();
mFacade.RegisterObserver(GameEventType.EnemyKilled,new EnemyKilledObserverStageSystem(this));
}
public override void Update()
{
base.Update();
mRootHandler.Handler(mLV);
}
//初始化敌人的出生位置
private void InitPos()
{
mEnemySpawnPosList = new List<Vector3>();
int i = 1;
while (true)
{
GameObject go = GameObject.Find("Position"+i);
if (go != null)
{
mEnemySpawnPosList.Add(go.transform.position);
go.SetActive(false);
i++;
}
else
break;
}
mTargetPos = GameObject.Find("TargetPosition").transform.position;
}
private Vector3 GetEnemyRandomSpawnPos()
{
return mEnemySpawnPosList[Random.Range(0, mEnemySpawnPosList.Count)];
}
//初始化关卡的责任链
private void InitStageChain()
{
省略……
}
//得到敌人死亡的数量
public int GetCountOfEnemyKilled()
{
return mCountOfEnemyKilled;
}
//进入下一个关卡的方法
public void EnterNextStage()
{
//TODO
mLV++;
}
}
public class EnemyKilledObserverStageSystem : IGameEventObserver
{
private StageSystem mStageSystem;
private EnemyKilledSubject mSubject;
public EnemyKilledObserverStageSystem(StageSystem stageSystem)
{
mStageSystem = stageSystem;
}
public override void SetSubject(IGameEventSubject sub)
{
mSubject = sub as EnemyKilledSubject;
}
public override void Updates()
{
mStageSystem.CountOfEnemyKilled = mSubject.EnemyKilled;
}
}
GameFacade:
public void RegisterObserver(GameEventType eventType, IGameEventObserver obs)
{
gameEventSystem.RegisterObserver(eventType, obs);
}
public void RemoveObserver(GameEventType eventType, IGameEventObserver obs)
{
gameEventSystem.RemoveObserver(eventType, obs);
}
public void NotifyObserver(GameEventType eventType)
{
gameEventSystem.NotifyObserver(eventType);
}
IEnemy:
protected override void Killed()
{
base.Killed();
GameFacade.Instance.NotifyObserver(GameEventType.EnemyKilled);
}
成就系统的开发:
创建成就系统AchievementSystem ,初始化时注册对敌人死亡,士兵死亡,关卡等级观察者的注册
并声明对应的三个增加数量的方法
public class AchievementSystem : IGameSystem
{
private int mEnemyKilledCount = 0;
private int mSoldierKilledCount = 0;
private int mMaxStageLV = 1;
public override void Init()
{
base.Init();
mFacade.RegisterObserver(GameEventType.EnemyKilled, new EnemyKilledObserverAchievement(this));
mFacade.RegisterObserver(GameEventType.SoldierKilled, new SoldierKilledObserverAchievement(this));
mFacade.RegisterObserver(GameEventType.NewStage, new NewStageObserverAchievement(this));
}
public void AddEnemyKilledCount(int number = 1)
{
mEnemyKilledCount += number;
}
public void AddSoldierKilledCount(int number = 1)
{
mSoldierKilledCount += number;
}
public void AddMaxStageLV(int stageLV)
{
if (stageLV <= mMaxStageLV) return;
mMaxStageLV = stageLV;
}
}
士兵、敌人死亡成就的更新
在IEnemy和ISoldier重写的Killed()角色死亡方法中调用GameFacade中的通知方法NotifyObserver,通知所有观察者
public class EnemyKilledObserverStageSystem : IGameEventObserver
{
private StageSystem mStageSystem;
private EnemyKilledSubject mSubject;
public EnemyKilledObserverStageSystem(StageSystem stageSystem)
{
mStageSystem = stageSystem;
}
public override void SetSubject(IGameEventSubject sub)
{
mSubject = sub as EnemyKilledSubject;
}
public override void Updates()
{
mStageSystem.CountOfEnemyKilled = mSubject.EnemyKilled;
}
}
public class SoldierKilledObserverAchievement : IGameEventObserver
{
private SoldierKilledSubject mSub;
private AchievementSystem mAchievementSystem;
public SoldierKilledObserverAchievement(AchievementSystem achievementSystem)
{
mAchievementSystem = achievementSystem;
}
public override void SetSubject(IGameEventSubject sub)
{
mSub = sub as SoldierKilledSubject;
}
public override void Updates()
{
mAchievementSystem.AddSoldierKilledCount();
}
}
ISoldier:
protected override void Killed()
{
base.Killed();
GameFacade.Instance.NotifyObserver(GameEventType.SoldierKilled);
}
IEnemy:
protected override void Killed()
{
base.Killed();
GameFacade.Instance.NotifyObserver(GameEventType.EnemyKilled);
}
已达到最高关卡等级的成就:
在StageSystem的EnterNextStage()进入下一个关卡的方法中,调用通知方法:
public class NewStageObserverAchievement : IGameEventObserver
{
private NewStageSubject mSub;
private AchievementSystem mAchievementSystem;
public NewStageObserverAchievement(AchievementSystem achievementSystem)
{
mAchievementSystem = achievementSystem;
}
public override void SetSubject(IGameEventSubject sub)
{
mSub = sub as NewStageSubject;
}
public override void Updates()
{
mAchievementSystem.AddMaxStageLV(mSub.CurrentStage);
}
}
StageSystem:
//进入下一个关卡的方法
public void EnterNextStage()
{
mLV++;
mFacade.NotifyObserver(GameEventType.NewStage);
}