遊戲設計模式---------觀察者模式(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();
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章