1. 程式人生 > >Unity3D學習筆記(二十四):MVC框架

Unity3D學習筆記(二十四):MVC框架

初始 中心 player component sage 私有構造函數 展現 sys 技術

MVC:全名是Model-View-Controller View(視圖層 - 頂層) Controller(控制層 - 中層) Model(數據層 - 底層) View(視圖層) 說明:展現給玩家的(包括UI,包括場景中的一些表現) 註意:View層不能對Model的數據進行修改,但是能對Model的數據進行訪問 功能: 1、數據的展現 2、管理自己面板的一些邏輯 3、實現用戶界面的按鈕的操作邏輯 Model(數據層) 說明:位於Frame最底層,屬於數據中心 功能: 1、存放數據 2、提供修改訪問數據的方法 3、通知View層數據已經發生改變,需要更新界面(通過事件) Controller(控制層) 說明:對Model層具有訪問和修改的權限。 功能: 1、根據邏輯對Model層的數據進行修改。 2、回調View的方法通知操作完成或者失敗 MVC的優點: 1、工程結構更加的清晰 2、提高代碼的可讀性,封裝性,擴展性 3、提高工作效率 遊戲界面實例 畫布尺寸1280x720 技術分享圖片

把原圖當作底圖,調整透明度,去添加調整元素位置

技術分享圖片

描邊組件

技術分享圖片

取消滑動條的交互

技術分享圖片

代碼邏輯 視圖層: 延遲函數問題:連續點擊時會生成多個延遲函數,未消失的延遲函數,會影響到下次調用結果
代碼邏輯
視圖層:
延遲函數問題:連續點擊時會生成多個延遲函數,未消失的延遲函數,會影響到下次調用結果
控制層:用單例模式抽象封裝方法 提示界面問題:用委托和回調方法來實現
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerController
{
    
private static PlayerController instance; public static PlayerController Instance { get { if (instance == null) { instance = new PlayerController(); } return instance; } } private PlayerController(){ }
public delegate void Del(string str); /// <summary> /// 增加經驗的方法,參數是增加的經驗 /// </summary> /// <param name="exp"></param> public void AddExp(float exp) { //人物死亡不能獲得經驗 if (PlayerData.Instance.CurrentHP > 0) { PlayerData.Instance.CurrentExp += exp; //遞歸判斷是否升級 CheckLevelUp(); } else { Debug.Log("人物死亡"); } } /// <summary> /// 使用遞歸判斷是否升級 /// </summary> void CheckLevelUp() { if (PlayerData.Instance.CurrentExp >= PlayerData.Instance.MaxExp) { PlayerData.Instance.CurrentExp -= PlayerData.Instance.MaxExp; PlayerData.Instance.Level++; PlayerData.Instance.Gold += PlayerData.Instance.Level * 100;//每次升級需要增加玩家金幣 CheckLevelUp(); } } /// <summary> /// 購買金幣,參數的購買的 100 * num /// /// </summary> /// <param name="gold"></param> public void BuyGoldByDiamonds(int num, Del callback) { //金幣比鉆石 2 : 1 //判斷鉆石的數量是否夠用 if (PlayerData.Instance.Diamonds >= (num * 100 * 0.5f)) { PlayerData.Instance.Diamonds -= (num * 50); PlayerData.Instance.Gold += (num * 100); } else { Debug.Log("鉆石不足,請充值"); //告訴調用的人,鉆石不夠了 if (callback != null) { callback("鉆石不足,請充值,沒錢玩什麽遊戲!"); } } } public void Hit(float value, Del callback) { if (PlayerData.Instance.CurrentHP > 0) { PlayerData.Instance.CurrentHP = PlayerData.Instance.CurrentHP >= value ? PlayerData.Instance.CurrentHP - value : 0; } else { Debug.Log("玩家已經死亡"); if (callback != null) { callback("玩家已經死亡,不能鞭屍!!!!!"); } } } /// <summary> /// 通過金幣購買血量 10 : 1 /// </summary> /// <param name="hp"></param> public void AddHPByGold(float hp) { if (PlayerData.Instance.CurrentHP <= 0) { Debug.Log("玩家已經死亡"); } else { int gold = (int)Mathf.Ceil(hp * 0.1f); if (PlayerData.Instance.Gold >= gold) { PlayerData.Instance.Gold -= gold; PlayerData.Instance.CurrentHP += hp; PlayerData.Instance.CurrentHP = PlayerData.Instance.CurrentHP > PlayerData.Instance.MaxHP ? PlayerData.Instance.MaxHP : PlayerData.Instance.CurrentHP; } else { Debug.Log("金幣不夠"); } } } public void ResetLife() { if (PlayerData.Instance.CurrentHP <= 0) { if (PlayerData.Instance.Diamonds >= 100) { PlayerData.Instance.Diamonds -= 100; PlayerData.Instance.CurrentHP = PlayerData.Instance.MaxHP * 0.5f; } else { Debug.Log("鉆石不足, 請充值! 沒錢,玩什麽遊戲!"); } } else { Debug.Log("玩家還沒死呢,復什麽活!"); } } /// <summary> /// 充值 /// </summary> public void Recharge(int diamonds) { PlayerData.Instance.Diamonds += diamonds; } }
數據層:用單例模式管理數據,提供修改訪問數據的方法 數據刷新和同步問題:用屬性對字段進行封裝,用事件儲存需要監控當前數據變化的界面的方法,當訪問屬性的時候,調用事件函數
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
//所有的數據都已經放在PlayerData裏了
public class PlayerData
{
    //未繼承Mono的單例
    //1、先有一個私有的靜態的自己的實例
    private static PlayerData instance;
    //2、提供一個訪問實例的屬性或者方法
    public static PlayerData Instance
    {
        get
        {
            //判斷實例是否為null
            if (instance == null)
            {
                instance = new PlayerData();
            }
            return instance;
        }
    }
    public string PlayerName
    {
        get
        {
            return playerName;
        }
        set
        {
            if (playerName != value)
            {
                //通知界面更新
                playerName = value;
                Debug.Log("值發生改變,更新界面");
                UpdatePanel();
            }
        }
    }
    public float MaxHP
    {
        get
        {
            return maxHP;
        }
        set
        {
            if (maxHP != value)
            {
                maxHP = value;
                Debug.Log("值發生改變,更新界面");
                UpdatePanel();
            }
        }
    }
    public float CurrentHP
    {
        get
        {
            return currentHP;
        }
        set
        {
            if (currentHP != value)
            {
                currentHP = value;
                Debug.Log("值發生改變,更新界面");
                UpdatePanel();
            }
        }
    }
    public float MaxExp
    {
        get
        {
            return maxExp;
        }
        set
        {
            if (maxExp != value)
            {
                maxExp = value;
                Debug.Log("值發生改變,更新界面");
                UpdatePanel();
            }
        }
    }
    public float CurrentExp
    {
        get
        {
            return currentExp;
        }
        set
        {
            if (currentExp != value)
            {
                currentExp = value;
                Debug.Log("值發生改變,更新界面");
                UpdatePanel();
            }
        }
    }
    public int Level
    {
        get
        {
            return level;
        }
        set
        {
            if (level != value)
            {
                level = value;
                Debug.Log("值發生改變,更新界面");
                UpdatePanel();
            }
        }
    }
    public int Gold
    {
        get
        {
            return gold;
        }
        set
        {
            if (gold != value)
            {
                gold = value;
                Debug.Log("值發生改變,更新界面");
                UpdatePanel();
            }
        }
    }
    public int Diamonds
    {
        get
        {
            return diamonds;
        }
        set
        {
            if (diamonds != value)
            {
                diamonds = value;
                Debug.Log("值發生改變,更新界面");
                UpdatePanel();
            }
        }
    }
    //3、私有構造函數
    private PlayerData()
    {
        //私有構造函數裏進行數據的初始化
        PlayerName = "寒冰射手";
        MaxHP = 500;
        CurrentHP = 400;
        MaxExp = 1000;
        CurrentExp = 500;
        Level = 1;
        Gold = 500;
        Diamonds = 0;
    }
    private string playerName;
    private float maxHP;
    private float currentHP;
    private float maxExp;
    private float currentExp;
    private int level;
    private int gold;
    private int diamonds;
    //1.聲明一個委托類型
    public delegate void Del();
    //2.聲明一個事件變量
    public event Del updateEvent;//這個事件裏存儲了所有的需要監控當前數據變化的界面的方法
    void UpdatePanel()
    {
        //通知界面更新,不知道有多少界面,
        //可以使用委托=事件的方式,來通知所有的界面
        if (updateEvent != null)
        {
            updateEvent();
        }
    }
}

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class UGUI_Shop : MonoBehaviour
{
    private Button expButton;
    private Button goldButton;
    private Button diamondsButton;
    private void Awake()
    {
        expButton = transform.Find("Button1").GetComponent<Button>();
        goldButton = transform.Find("Button2").GetComponent<Button>();
        diamondsButton = transform.Find("Button3").GetComponent<Button>();
        expButton.onClick.AddListener(BuyExpClick);
        goldButton.onClick.AddListener(BuyGoldClick);
        diamondsButton.onClick.AddListener(BuyDiamondsClick);
    }
    void BuyExpClick()
    {
        PlayerController.Instance.AddExp(100);
    }
    void BuyGoldClick()
    {
        PlayerController.Instance.BuyGoldByDiamonds(1, null);
    }
    void BuyDiamondsClick()
    {
        PlayerController.Instance.Recharge(100);
    }
    // Use this for initialization
    void Start()
    {
    }
    // Update is called once per frame
    void Update()
    {
    }
}

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class UGUI_Message : MonoBehaviour {
    private Text nameText;
    private Text hpText;
    private Text expText;
    private Text levelText;
    void Awake()
    {
        nameText = transform.Find("Text1").GetComponent<Text>();
        hpText = transform.Find("Text2").GetComponent<Text>();
        expText = transform.Find("Text3").GetComponent<Text>();
        levelText = transform.Find("Text4").GetComponent<Text>();
        //當數據改變時,需要更新界面,把更新界面的方法添加到PlayerData的事件裏去
        PlayerData.Instance.updateEvent += UpdatePanel;
    }
    // Use this for initialization
    void Start()
    {
        UpdatePanel();//數據初始化
    }
    private void OnDestroy()
    {
        //當界面銷毀的時候,不需要去監聽數據的變化了,把事件移除
        PlayerData.Instance.updateEvent -= UpdatePanel;
    }
    //數值發生改變的時候,更新界面
    public void UpdatePanel()
    {
        nameText.text = "名字:" + PlayerData.Instance.PlayerName;
        hpText.text = "血量:" + ((int)PlayerData.Instance.CurrentHP).ToString()
            + "/" + ((int)PlayerData.Instance.MaxHP).ToString();
        expText.text = "經驗:" + ((int)PlayerData.Instance.CurrentExp).ToString()
           + "/" + ((int)PlayerData.Instance.MaxExp).ToString();
        levelText.text = "等級:" + PlayerData.Instance.Level.ToString();
    }
}

Unity3D學習筆記(二十四):MVC框架