设计模式实战学习笔记(五):责任链、观察者模式

(十五)责任链模式(关卡系统)

责任链模式的代码实现:

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);
    }

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值