using System.Collections;
using System.Collections.Generic;
using UnityEngine;
/*
* Author:W
* 游戏事件系统
*/
namespace DesignPattern_Observer
{
#region 事件主题实现
/// <summary>
/// 游戏事件主题的基类
/// </summary>
public abstract class GameBaseEventSubject
{
/// <summary>
/// 订阅了该游戏事件主题的所有观察者集合
/// </summary>
private List<GameBaseEventObserver> GameEventObserverList = new List<GameBaseEventObserver>();
/// <summary>
/// 事件发生时,所携带的参数
/// </summary>
private System.Object Param = null;
/// <summary>
/// 添加该游戏事件主题的观察者
/// </summary>
/// <param name="gameBaseEventObserver"></param>
public void Attach(GameBaseEventObserver gameBaseEventObserver)
{
if (GameEventObserverList == null)
GameEventObserverList = new List<GameBaseEventObserver>();
if (!GameEventObserverList.Contains(gameBaseEventObserver))
GameEventObserverList.Add(gameBaseEventObserver);
}
/// <summary>
/// 取消该游戏事件主题一个观察者
/// </summary>
/// <param name="gameBaseEventObserver"></param>
public void Detach(GameBaseEventObserver gameBaseEventObserver)
{
if (GameEventObserverList == null) return;
if (GameEventObserverList.Contains(gameBaseEventObserver))
GameEventObserverList.Remove(gameBaseEventObserver);
}
/// <summary>
/// 事件主题发生改变,去通知其所有观察者
/// </summary>
public void Notify()
{
if (GameEventObserverList == null) return;
foreach (GameBaseEventObserver gameBaseEventObserver in GameEventObserverList)
{
if (gameBaseEventObserver != null)
gameBaseEventObserver.Update();
}
}
/// <summary>
/// 参数设置
/// </summary>
/// <param name="Param"></param>
public virtual void SetParam(System.Object Param)
{
this.Param = Param;
}
}
/// <summary>
/// 主题1
/// </summary>
public class Subject1 : GameBaseEventSubject
{
private int a =0;
public Subject1() { }
public void method1() { }
private void method2() { }
/// <summary>
/// 参数设置处理,然后通知观察者
/// </summary>
/// <param name="Param"></param>
public override void SetParam(System.Object Param)
{
base.SetParam(Param);
//----处理一些游戏事件------
// 参数对象解析出来,做一些事情
// class1 = Param as Class1
//------------------------
//然后通知
Notify();
}
}
#endregion
#region 事件观察者实现
/// <summary>
/// 游戏事件观察者的基类【在实际应用环境中,为避免产生过多的观察者类时,可以换成委托回调函数,效果是类似的】
/// </summary>
public abstract class GameBaseEventObserver
{
/// <summary>
/// 监听的游戏事件主题发生改变时,更新自身
/// </summary>
public abstract void Update();
/// <summary>
/// 设置观察的主题【方便访问到主题】
/// </summary>
public virtual void SetSubject(GameBaseEventSubject gameBaseEventSubject) { }
}
/// <summary>
/// 观察者1
/// </summary>
public class Observer1 : GameBaseEventObserver
{
#region 主题获取[需要访问主题时,可有可无]
/// <summary>
/// 该观察者监听的具体主题
/// </summary>
private Subject1 Subject = null;
/// <summary>
/// 主题设置
/// </summary>
/// <param name="gameBaseEventSubject"></param>
public override void SetSubject(GameBaseEventSubject gameBaseEventSubject)
{
Subject = gameBaseEventSubject as Subject1;
}
#endregion
#region 与该观察者绑定的系统
//private System1 system1 = null;
//public Observer1(System1 system1)
//{
// this.system1 = system1;
//}
#endregion
/// <summary>
/// Subject1更新通知下发,观察者来处理
/// </summary>
public override void Update()
{
//-------该观察者将监听到的信息,给绑定的【一对一】系统,让其做事情-----------
// system1.xxx();
//-----------------------
}
}
#endregion
/// <summary>
/// 游戏事件类型
/// </summary>
public enum GameEvent
{
None,
EnemyKilled,
AddScore,
Upgrade,
NewStage,
//.....
}
/// <summary>
/// 游戏事件系统
/// </summary>
public class GameEventSystem
{
/// <summary>
/// 游戏事件及其对应的主题映射集合
/// </summary>
private Dictionary<GameEvent, GameBaseEventSubject> GameEventDic = new Dictionary<GameEvent, GameBaseEventSubject>();
public GameEventSystem()
{
Init();
}
/// <summary>
/// 初始化
/// </summary>
private void Init()
{
// NotDo
}
#region 为事件主题注册与注销观察者 【供需要监听该事件主题的系统调用】
/// <summary>
/// 为特定事件主题注册一个特定的观察者
/// </summary>
/// <param name="gameEvent"></param>
/// <param name="gameObserver"></param>
public void RegisterObserver(GameEvent gameEvent, GameBaseEventObserver gameObserver)
{
GameBaseEventSubject Subject = GetGameEventSubject(gameEvent);
if (Subject != null)
{
Subject.Attach(gameObserver);
gameObserver.SetSubject(Subject);
}
}
/// <summary>
/// 为特定事件主题注销某个特定的观察者
/// </summary>
/// <param name="gameEvent"></param>
/// <param name="gameObserver"></param>
public void UnRegisterObserver(GameEvent gameEvent, GameBaseEventObserver gameObserver)
{
GameBaseEventSubject Subject = GetGameEventSubject(gameEvent);
if (Subject != null)
Subject.Detach(gameObserver);
}
/// <summary>
/// 事件主题获取
/// </summary>
/// <param name="gameEvent"></param>
/// <returns></returns>
private GameBaseEventSubject GetGameEventSubject(GameEvent gameEvent)
{
if (GameEventDic == null)
GameEventDic = new Dictionary<GameEvent, GameBaseEventSubject>();
//集合里有
if (GameEventDic.ContainsKey(gameEvent))
return GameEventDic[gameEvent];
//注册新的事件主题
GameBaseEventSubject targetSubject = null;
switch (gameEvent)
{
case GameEvent.AddScore:
targetSubject = new Subject1();
break;
case GameEvent.EnemyKilled:
//targetSubject = new Subject2();
break;
default:
Debug.LogError("还没有对该游戏事件:"+gameEvent+" 产生对应的主题类");
break;
}
if (targetSubject != null)
GameEventDic.Add(gameEvent, targetSubject);
return targetSubject;
}
#endregion
#region 事件通知更新下发【供事件主题产生者(如其他目标系统),在满足条件触发时调用,通知其所有的观察者】
/// <summary>
/// 游戏事件通知更新
/// </summary>
/// <param name="gameEvent"></param>
/// <param name="Param"></param>
public void NotifySubject(GameEvent gameEvent,System.Object Param)
{
if (!GameEventDic.ContainsKey(gameEvent)) return;
GameEventDic[gameEvent].SetParam(Param);
}
#endregion
/// <summary>
/// 销毁释放
/// </summary>
private void Release()
{
if (GameEventDic != null)
GameEventDic.Clear();
}
}
}
观察者模式-实际应用-游戏事件系统
最新推荐文章于 2021-09-06 08:10:00 发布