游戏设计模式---------观察者模式(Observer)

定义

定义了对象间一对多的依赖关系,当一个对象(主题Subject)状态发生改变时,所依赖它的对象(观察者Observer)将得到通知并自动更新状态。
主题接口一般包含的方法:

  1. RegisterObserver(Observer o):注册新的观察者
  2. RemoveObserver(Observer o):删除旧的观察者
  3. Notify(…):通知观察更新

观察者接口一般包含相应的收到通知进行更新操作。

优点:

  1. 依赖接口编程,能够使不同系统通过低耦合的方式进行通信,减少了不相关系统间代码的耦合。
  2. 容易实现一对多的依赖关系,只需要维护一个Observer数组就能给不同对象发送通知。

缺点:

  1. Observer数组需要进行动态内存管理
  2. 通知信息是遍历Observer数组依次发送,在处理多线程问题时可能出现差错,前一个对象事件处理时间较长会造成下一个对象事件延迟。若观察者对象间存在联系,在执行顺序不同时可能会产生差错。

例子

游戏角色系统(Subject)给UI系统(Observer)发送通知,实现实时显示角色血量状态。

Subject接口:

    public void UpdataINFO(int hp, int mp)
    {
        throw new System.NotImplementedException();
    }

Observer口

public interface IObserver {

    //更新角色血量蓝量信息
    void UpdataINFO(int hp, int mp);

}

角色系统(PlayerControl)

public class PlayerControl : MonoBehaviour,ISubject {

    //维护一个观察者对象数组
    private List<IObserver> observes;
    private int Hp = 100;
    private int Mp = 100;

    public GameObject UI;
    private UIManager uiManager;

    // Use this for initialization
    void Start () {
		observes = new List<IObserver>();
        //用例中手动加入  实践中可以动态加入观察者数组。
        uiManager = UI.GetComponent<UIManager>();
        observes.Add(uiManager);
	}
	
	// Update is called once per frame
	void Update () {
        if(Input.GetKey(KeyCode.W))
        {
            EatHpbag();
        }
        if(Input.GetKey(KeyCode.S))
        {
            EatMpbag();
        }
	}


    public void NotifyObserve()
    {
        for(int i=0;i<observes.Count;i++)
        {
            observes[i].UpdataINFO(Hp, Mp);
        }
    }

    public void RegisterObserve(IObserver observer)
    {
        observes.Add(observer);
    }

    public void RemoveObserve(IObserver observer)
    {
        int i = observes.IndexOf(observer);
        if(i>=0)
        {
            observes.RemoveAt(i);
        }
    }

    public void EatHpbag()
    {
        Hp++;
        NotifyObserve();
    }

    public void EatMpbag()
    {
        Mp++;
        NotifyObserve();
    }

}

UI系统(UIManager)

public class UIManager : MonoBehaviour, IObserver {

    public GameObject HpText;
    public GameObject MpText;
    private Text Hp;
    private Text Mp;

    // Use this for initialization
    void Start () {
        Hp = HpText.GetComponent<Text>();
        Mp = MpText.GetComponent<Text>();
	}
	

    public void UpdataINFO(int hp, int mp)
    {
        Hp.text = hp.ToString();
        Mp.text = mp.ToString();
    }
}
发布了2 篇原创文章 · 获赞 4 · 访问量 1272

猜你喜欢

转载自blog.csdn.net/qq_41655524/article/details/104264730