Unity3D学习笔记(二十四):MVC框架

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

猜你喜欢

转载自www.cnblogs.com/ciaowoo/p/10363592.html
今日推荐