Unity3D学习笔记(二十七):MVC框架下的背包系统(2)

Tools
FileTools
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.IO;
using System.Text;
public static class FileTools  {
    /// <summary>
    /// 读取指定路径的json文件
    /// </summary>
    /// <param name="path"></param>
    /// <returns></returns>
    public static string ReadJson(string path)
    {
        if (!File.Exists(path))
        {
            return "";
        }
        string json = "";
        StreamReader sr = new StreamReader(path, Encoding.UTF8);
        try
        {
            json = sr.ReadToEnd();
        }
        catch (System.Exception e)
        {
            Debug.Log(e.ToString());
        }
        sr.Close();
        return json;
    }
    /// <summary>
    /// 把json写入指定的文件a
    /// </summary>
    /// <param name="path"></param>
    /// <param name="json"></param>
    public static void WriteJson(string path, string json)
    {
        if (!File.Exists(path))
        {
            FileStream fs = File.Create(path);
            fs.Close();
        }
        StreamWriter sw = new StreamWriter(path, false, Encoding.UTF8);
        try
        {
            sw.Write(json);
        }
        catch (System.Exception e)
        {
            Debug.Log(e.ToString());
        }
        sw.Close();
    }
       
       
}

SaveManager

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class SaveManager
{
    #region 单例
    private static SaveManager instance;
    public static SaveManager Instance
    {
        get {
            if (null == instance)
            {
                instance = new SaveManager();
            }
            return instance;
        }
    }
    private SaveManager() { }
    #endregion
    /// <summary>
    /// 初始化数据
    /// </summary>
    public void InitData()
    {
        //初始化人物的数据
        string playerJson = FileTools.ReadJson(Application.streamingAssetsPath + "/Json/PlayerData.txt");
        if (playerJson == "")
        {
            PlayerData.SetInstance(null);
        }
        else
        {
            PlayerData.SetInstance(JsonUtility.FromJson<PlayerData>(playerJson));         
        }
        //Debug.Log(PlayerData.Instance.Atk);
        PlayerData.Instance.Init();
        //初始化背包数据
        string bagJson = FileTools.ReadJson(Application.streamingAssetsPath + "/Json/Bag.txt");
        if (bagJson == "")
        {
            BagData.SetInstance(null);
        }
        else
        {
            BagData.SetInstance(JsonUtility.FromJson<BagData>(bagJson));
        }
        //for (int i = 0; i < BagData.Instance.Items.Count; i++)
        //{
        //    Debug.Log("");
        //}
        BagData.Instance.UpdateCurrentCapacity();//更新一次负重
    }
    /// <summary>
    /// 保存数据
    /// </summary>
    public void SaveData()
    {
        //保存玩家的数据
        string playerJson = JsonUtility.ToJson(PlayerData.Instance, true);
        FileTools.WriteJson(Application.streamingAssetsPath + "/Json/PlayerData.txt", playerJson);
        //保存背包的数据
        string bagJson = JsonUtility.ToJson(BagData.Instance, true);
        FileTools.WriteJson(Application.streamingAssetsPath + "/Json/Bag.txt", bagJson);
    }
}

GameManager

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class GameManager : MonoBehaviour {
       // Use this for initialization
       void Awake () {
        DontDestroyOnLoad(gameObject);
        SaveManager.Instance.InitData();
       }
       
       // Update is called once per frame
       void OnDestroy () {
        SaveManager.Instance.SaveData();
    }
}
Json
PlayerData
{
    "items": [
        {
            "id": 2,
            "itemName": "肚兜",
            "iconName": "FaShi_XiongJia_5",
            "atk": 0.0,
            "def": 999.0,
            "thump": 0.0,
            "hp": 1000.0,
            "mp": 2000.0,
            "anger": 0.0,
            "weight": 1.0,
            "type": 2
        },
        {
            "id": 1,
            "itemName": "大贱",
            "iconName": "DaJian_08",
            "atk": 999.0,
            "def": 0.0,
            "thump": 0.9900000095367432,
            "hp": 100.0,
            "mp": 100.0,
            "anger": 500.0,
            "weight": 2.0,
            "type": 0
        }
    ],
    "atk": 20.0,
    "def": 20.0,
    "thump": 0.5,
    "hp": 100.0,
    "mp": 100.0,
    "anger": 0.0
}

Bag

{
    "items": [
        {
            "id": 3,
            "itemName": "肚兜",
            "iconName": "FaShi_XiongJia_4",
            "atk": 0.0,
            "def": 999.0,
            "thump": 0.0,
            "hp": 1000.0,
            "mp": 2000.0,
            "anger": 0.0,
            "weight": 1.0,
            "type": 2
        },
        {
            "id": 4,
            "itemName": "大贱",
            "iconName": "DaJian_08",
            "atk": 999.0,
            "def": 0.0,
            "thump": 0.9900000095367432,
            "hp": 100.0,
            "mp": 100.0,
            "anger": 500.0,
            "weight": 2.0,
            "type": 0
        },
        {
            "id": 5,
            "itemName": "肚兜",
            "iconName": "FaShi_XiongJia_5",
            "atk": 0.0,
            "def": 999.0,
            "thump": 0.0,
            "hp": 1000.0,
            "mp": 2000.0,
            "anger": 0.0,
            "weight": 1.0,
            "type": 2
        },
        {
            "id": 6,
            "itemName": "肚兜",
            "iconName": "FaShi_XiongJia_4",
            "atk": 0.0,
            "def": 999.0,
            "thump": 0.0,
            "hp": 1000.0,
            "mp": 2000.0,
            "anger": 0.0,
            "weight": 1.0,
            "type": 2
        },
        {
            "id": 2,
            "itemName": "肚兜",
            "iconName": "FaShi_XiongJia_5",
            "atk": 0.0,
            "def": 999.0,
            "thump": 0.0,
            "hp": 1000.0,
            "mp": 2000.0,
            "anger": 0.0,
            "weight": 1.0,
            "type": 2
        },
        {
            "id": 1,
            "itemName": "大贱",
            "iconName": "DaJian_08",
            "atk": 999.0,
            "def": 0.0,
            "thump": 0.9900000095367432,
            "hp": 100.0,
            "mp": 100.0,
            "anger": 500.0,
            "weight": 2.0,
            "type": 0
        },
        {
            "id": 7,
            "itemName": "肚兜",
            "iconName": "FaShi_XiongJia_4",
            "atk": 0.0,
            "def": 999.0,
            "thump": 0.0,
            "hp": 1000.0,
            "mp": 2000.0,
            "anger": 0.0,
            "weight": 1.0,
            "type": 2
        }
    ],
    "maxCapacity": 100.0
}
Model
ItemData
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
/// <summary>
/// 该类用于存储装备的基本属性
/// </summary>
[System.Serializable]//因为对于已有的数据是从文件中来的,所以需要加序列化标识
public class ItemData
{
    #region 私有变量
    [SerializeField]
    private int id;//作为物品的唯一标识
    [SerializeField]
    private string itemName;//物品的名字
    [SerializeField]
    private string iconName;//物品显示图片的名字
    [SerializeField]
    private float atk;//攻击力加成
    [SerializeField]
    private float def;//防御力加成
    [SerializeField]
    private float thump;//暴击率加成
    [SerializeField]
    private float hp;//血量加成
    [SerializeField]
    private float mp;//加成
    [SerializeField]
    private float anger;//怒气加成
    [SerializeField]
    private float weight;//重量
    [SerializeField]
    private ItemType type;//物品的类型
    #endregion
    #region 属性
    public int Id
    {
        get
        {
            return id;
        }
    }
    public string ItemName
    {
        get
        {
            return itemName;
        }
    }
    public string IconName
    {
        get
        {
            return iconName;
        }
    }
    public float Atk
    {
        get
        {
            return atk;
        }
    }
    public float Def
    {
        get
        {
            return def;
        }
    }
    public float Thump
    {
        get
        {
            return thump;
        }
    }
    public float Hp
    {
        get
        {
            return hp;
        }
    }
    public float Mp
    {
        get
        {
            return mp;
        }
    }
    public float Anger
    {
        get
        {
            return anger;
        }
    }
    public float Weight
    {
        get
        {
            return weight;
        }
    }
    public ItemType Type
    {
        get
        {
            return type;
        }
    }
    #endregion
    #region 构造函数
    public ItemData() { }
    public ItemData(int id, string itemName, string iconName, float atk,
        float def, float thump, float hp, float mp, float anger, float weight, ItemType type)
    {
        this.id = id;
        this.itemName = itemName;
        this.iconName = iconName;
        this.atk = atk;
        this.def = def;
        this.thump = thump;
        this.hp = hp;
        this.mp = mp;
        this.anger = anger;
        this.weight = weight;
        this.type = type;
    }
    #endregion
    public static string GetTypeName(ItemType type)
    {
        string typeName = "";
        switch (type)
        {
            case ItemType.Weapon:
                typeName = "武器";
                break;
            case ItemType.Cap:
                typeName = "头盔";
                break;
            case ItemType.Armour:
                typeName = "铠甲";
                break;
            case ItemType.Belt:
                typeName = "腰带";
                break;
            case ItemType.Ring:
                typeName = "戒指";
                break;
            case ItemType.Headwear:
                typeName = "头饰";
                break;
            case ItemType.Necklace:
                typeName = "项链";
                break;
            case ItemType.Shoe:
                typeName = "靴子";
                break;
        }
        return typeName;
    }
}

ItemType

/// <summary>
/// 物品的类型, 装备栏能装备的类型
/// </summary>
public enum ItemType
{
    Weapon,//武器
    Cap,//头盔
    Armour,//铠甲
    Ring,//戒指
    Belt,//腰带
    Necklace,//项链
    Shoe,//鞋子
    Headwear,//头饰
}
PlayerData
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;
public class PlayerData
{
    #region 单例
    private static PlayerData instance;//这个数据类的单例,从文件中反序列化来的
    public static PlayerData Instance
    {
        get {
            return instance;
        }
    }
    private PlayerData() { }
    /// <summary>
    /// 对单例进行赋值
    /// </summary>
    /// <param name="data"></param>
    public static void SetInstance(PlayerData data)
    {
        if (null == data)
        {
            instance = new PlayerData();
        }
        else
        {
            instance = data;
        }
    }
    #endregion
    public List<ItemData> items;//人物身上穿戴的装备
    #region 私有变量
    [SerializeField]
    private float atk;//基础攻击力
    [SerializeField]
    private float def;//基础防御力
    [SerializeField]
    private float thump;//基础暴击率
    [SerializeField]
    private float hp;//基础血量
    [SerializeField]
    private float mp;//基础魔法
    [SerializeField]
    private float anger;//基础怒气
    //装备的属性加成都是装备的装备计算出来的
    private float addAtk;//装备攻击力加成
    private float addDef;//
    private float addThump;//
    private float addHp;//
    private float addMp;//
    private float addAnger;//
    #endregion
    #region 事件
    //当数据发生改变时,通过该事件通知界面
    public event Action updateEvent;
    #endregion
    #region 属性
    public float Atk
    {
        get
        {
            return atk;
        }
    }
    public float Def
    {
        get
        {
            return def;
        }
    }
    public float Thump
    {
        get
        {
            return thump;
        }
    }
    public float Hp
    {
        get
        {
            return hp;
        }
    }
    public float Mp
    {
        get
        {
            return mp;
        }
    }
    public float Anger
    {
        get
        {
            return anger;
        }
    }
    public float AddAtk
    {
        get
        {
            return addAtk;
        }
    }
    public float AddDef
    {
        get
        {
            return addDef;
        }
    }
    public float AddThump
    {
        get
        {
            return addThump;
        }
    }
    public float AddHp
    {
        get
        {
            return addHp;
        }
    }
    public float AddMp
    {
        get
        {
            return addMp;
        }
    }
    public float AddAnger
    {
        get
        {
            return addAnger;
        }
    }
    #endregion
    #region 提供一些访问或删除装备的方法
    /// <summary>
    /// 通过装备的ID来访问装备
    /// </summary>
    /// <param name="id"></param>
    /// <returns></returns>
    public ItemData GetItem(int id)
    {
        for (int i = 0; i < items.Count; i++)
        {
            if (id == items[i].Id)
            {
                return items[i];
            }
        }
        return null;
    }
    /// <summary>
    /// 通过装备的类型来访问装备
    /// </summary>
    /// <param name="type"></param>
    /// <returns></returns>
    public ItemData GetItem(ItemType type)
    {
        for (int i = 0; i < items.Count; i++)
        {
            if (type == items[i].Type)
            {
                return items[i];
            }
        }
        return null;
    }
    /// <summary>
    /// 添加装备
    /// </summary>
    /// <param name="data"></param>
    public void AddItem(ItemData data)
    {
        items.Add(data);
        //数据发生改变,装备的属性加成需要重新计算
        UpdateAdditionData();
        //数据发生变化,通知界面
        UpdatePanel();
    }
    /// <summary>
    /// 删除装备
    /// </summary>
    /// <param name="data"></param>
    public void RemoveItem(ItemData data)
    {
        if (items.Contains(data))
        {
            items.Remove(data);
            //数据发生改变,装备的属性加成需要重新计算
            UpdateAdditionData();
            //数据发生变化,通知界面
            UpdatePanel();
        }
    }
    /// <summary>
    /// 通过ID删除装备
    /// </summary>
    /// <param name="id"></param>
    public void RemoveItem(int id)
    {
        ItemData data = GetItem(id);
        RemoveItem(data);
    }
    /// <summary>
    /// 通过装备类型删除装备
    /// </summary>
    /// <param name="type"></param>
    public void RemoveItem(ItemType type)
    {
        ItemData data = GetItem(type);
        RemoveItem(data);
    }
    #endregion
    public void Init()
    {
        UpdateAdditionData();
    }
    /// <summary>
    /// 计算装备的加成数据, 每次当数据发生改变的时候调用
    /// </summary>
    void UpdateAdditionData()
    {
        this.addAtk = 0;
        this.addDef = 0;
        this.addThump = 0;
        this.addHp = 0;
        this.addMp = 0;
        this.addAnger = 0;
        //把每一件装备的加成数据加给实际的数据
        for (int i = 0; i < items.Count; i++)
        {
            this.addAtk += items[i].Atk;
            this.addDef += items[i].Def;
            this.addThump += items[i].Thump;
            this.addHp += items[i].Hp;
            this.addMp += items[i].Mp;
            this.addAnger += items[i].Anger;
        }
    }
    /// <summary>
    /// 通知界面改变
    /// </summary>
    void UpdatePanel()
    {
        if (updateEvent != null)
        {
            updateEvent();
        }
    }
}

BagData

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;
public class BagData
{
    #region 单例
    private static BagData instance;//从文件中反序列化来的
    public static BagData Instance
    {
        get {
            return instance;
        }
    }
    private BagData() { }
    public static void SetInstance(BagData data)
    {
        if (data == null)
        {
            instance = new BagData();
            instance.items = new List<ItemData>();
        }
        else
        {
            instance = data;
        }
    }
    #endregion
    #region 私有变量
    [SerializeField]
    private List<ItemData> items;//当前的所有的装备
    [SerializeField]
    private float maxCapacity;//最大容量, 从文件中读取进来的
    private float currentCapacity;//当前容量, 根据当前背包的装备计算出来的
    #endregion
    #region 事件
    public event Action updateEvent;//定义一个事件,当数据改变时,调用事件通知界面更新
    #endregion
    #region 属性
    public float MaxCapacity
    {
        get
        {
            return maxCapacity;
        }
    }
    public float CurrentCapacity
    {
        get
        {
            return currentCapacity;
        }
    }
    public List<ItemData> Items
    {
        get
        {
            return items;
        }
    }
    #endregion
    #region 提供一些操作背包装备的方法
    /// <summary>
    /// 使用ID访问背包中的装备
    /// </summary>
    /// <param name="id"></param>
    /// <returns></returns>
    public ItemData GetItem(int id)
    {
        for (int i = 0; i < items.Count; i++)
        {
            if (items[i].Id == id)
            {
                return items[i];
            }
        }
        return null;
    }
    /// <summary>
    /// 添加装备
    /// </summary>
    /// <param name="id"></param>
    public void AddItem(ItemData data)
    {
        items.Add(data);
        //每一次数据改变,当前负重都是需要重新计算的
        UpdateCurrentCapacity();
        //数据变了,通知界面
        UpdatePanel();
    }
    /// <summary>
    /// 删除装备
    /// </summary>
    /// <param name="data"></param>
    public void RemoveItem(ItemData data)
    {
        //判断data是否在Items里
        if (items.Contains(data))
        {
            items.Remove(data);
        }
        UpdateCurrentCapacity();
        //数据变了,通知界面
        UpdatePanel();
    }
    /// <summary>
    /// 删除指定ID的装备
    /// </summary>
    /// <param name="id"></param>
    public void RemoveItem(int id)
    {
        ItemData data = GetItem(id);
        if (data != null)
        {
            RemoveItem(data);
        }
    }
    #endregion
    public void UpdateCurrentCapacity()
    {
        currentCapacity = 0;
        //把每一件装备的负重累加在一起,就是当前的负重
        for (int i = 0; i < items.Count; i++)
        {
            currentCapacity += items[i].Weight;
        }
    }
    /// <summary>
    /// 通知界面更新
    /// </summary>
    void UpdatePanel()
    {
        if (updateEvent != null)
        {
            updateEvent();
        }
    }
    public void ItemsSort()
    {
        items.Sort(ItemSort);
        //物品之间的顺序发生了改变, 通知界面更新
        UpdatePanel();
    }
    /// <summary>
    /// 物品的排序,以物品的类型排
    /// </summary>
    /// <param name="a"></param>
    /// <param name="b"></param>
    /// <returns></returns>
    int ItemSort(ItemData a, ItemData b)
    {
        int tempA = (int)a.Type;
        int tempB = (int)b.Type;
        if (tempA < tempB)
        {
            return -1;
        }
        else if (tempA > tempB)
        {
            return 1;
        }
        else
        {
            return 0;
        }
    }
}
View
PlayerUI
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class PlayerUI : MonoBehaviour {
    private GridBase[] grids;//所有的装备栏
    //所有显示属性的Text
    private Text atkText;
    private Text defText;
    private Text thumpText;
    private Text hpText;
    private Text mpText;
    private Text angerText;
    void Awake () {
        //在子物体里获取所有的GridBase这个组件,返回的是一个数组
        grids = gameObject.GetComponentsInChildren<GridBase>();
        atkText = transform.Find("Message/AtkText").GetComponent<Text>();
        defText = transform.Find("Message/DefText").GetComponent<Text>();
        thumpText = transform.Find("Message/ThumpText").GetComponent<Text>();
        hpText = transform.Find("Message/HPText").GetComponent<Text>();
        mpText = transform.Find("Message/MPText").GetComponent<Text>();
        angerText = transform.Find("Message/AngerText").GetComponent<Text>();
        //ItemData data = new ItemData();
        //Debug.Log(JsonUtility.ToJson(data, true));
    }
    private void Start()
    {
        PlayerData.Instance.updateEvent += UpdatePanel;
        UpdatePanel();
    }
    private void OnDestroy()
    {
        PlayerData.Instance.updateEvent -= UpdatePanel;
    }
    /// <summary>
    /// 更新界面的方法
    /// </summary>
    void UpdatePanel()
    {
        //把人物身上装备的物品显示, 所有属性显示
        //先把所有的格子清空
        for (int i = 0; i < grids.Length; i++)
        {
            grids[i].UpdateItem(-1, "");
        }
        //再把人物身上装备显示在对应的格子上
        for (int i = 0; i < grids.Length; i++)
        {
            PlayerGridUI grid = grids[i] as PlayerGridUI;
            for (int j = 0; j < PlayerData.Instance.items.Count; j++)
            {
                //当格子的装备与人物数据里的装备的类型是一致时,证明该装备应该放在这个格子上
                if (grid.gridType == PlayerData.Instance.items[j].Type)
                {
                    grid.UpdateItem(PlayerData.Instance.items[j].Id, PlayerData.Instance.items[j].IconName);
                }
            }
        }
        atkText.text = "攻击力:" + PlayerData.Instance.Atk + "<color=\"green\"> + "
            + PlayerData.Instance.AddAtk + "</color>";
        defText.text = "防御力:" + PlayerData.Instance.Def + "<color=\"green\"> + "
            + PlayerData.Instance.AddDef + "</color>";
        thumpText.text = "暴击率:" + PlayerData.Instance.Thump + "<color=\"green\"> + "
            + PlayerData.Instance.AddThump + "</color>";
        hpText.text = "生命值:" + PlayerData.Instance.Hp + "<color=\"green\"> + "
            + PlayerData.Instance.AddHp + "</color>";
        mpText.text = "魔法值:" + PlayerData.Instance.Mp + "<color=\"green\"> + "
            + PlayerData.Instance.AddMp + "</color>";
        angerText.text = "怒气值:" + PlayerData.Instance.Anger + "<color=\"green\"> + "
            + PlayerData.Instance.AddAnger + "</color>";
    }
}

BagUI

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class BagUI : MonoBehaviour {
    private GridBase[] grids;
    private Text weightText;
    private Text numText;
    private Button rightButton;
    private Button leftButton;
    private Button clearUpButton;
    private int currentNum;
    private int maxNum;//根据背包里物品数量与当前有多少个格子比较
       void Awake () {
        //获取所有的格子
        grids = gameObject.GetComponentsInChildren<GridBase>();
        weightText = transform.Find("CapacityText").GetComponent<Text>();
        numText = transform.Find("Num/Num/Text").GetComponent<Text>();
        rightButton = transform.Find("Num/RightButton").GetComponent<Button>();
        leftButton = transform.Find("Num/LeftButton").GetComponent<Button>();
        clearUpButton = transform.Find("ClearUpButton").GetComponent<Button>();
        //按钮注册事件
        rightButton.onClick.AddListener(RightClick);
        leftButton.onClick.AddListener(LeftClick);
        clearUpButton.onClick.AddListener(ClearUpClick);
    }
    private void Start()
    {
        BagData.Instance.updateEvent += UpdatePanel;
        currentNum = 1;//界面一开始,当前页是1
        UpdatePanel();
    }
    private void OnDestroy()
    {
        BagData.Instance.updateEvent -= UpdatePanel;
    }
    /// <summary>
    /// 更新界面
    /// </summary>
    void UpdatePanel()
    {
        //更新当前页数的物品, 更新当前页数, 更新当前的负重
        //计算当前的最大页数
        maxNum = (int)Mathf.Ceil(BagData.Instance.Items.Count / (float)grids.Length);
        numText.text = currentNum + "/" + maxNum;
        weightText.text = "负重:" + BagData.Instance.CurrentCapacity + "/" +
            BagData.Instance.MaxCapacity;
       
        //显示当前的页数的物品
        //根据当前页数,确定第一个位置应该排背包数据的里的第几个索引(起始索引)
        //模拟 格子: 20   当第一页是起始索引为0, 当第二页时起始索引为20
        int startIndex = (currentNum - 1) * grids.Length;//(当前页数 - 1) * 格子数量
        //把从起始索引开始,依次的把物品放在对应的格子上
        for (int i = 0; i < grids.Length; i++)
        {
            //当i= 0时,证明是第一个格子,对应的物品索引 startIndex = startIndex + i
            //当i= 1时,证明是第二各格子,对应的物品索引 startIndex + 1 =  startIndex + i
            //....
            //当i = grids.Length - 1时, 最后一个格子, 对应的物品索引 startIndex + grids.Length - 1 =  startIndex + i
            //如果startIndex + i 超出了物品的数量, 证明这个格子没有物品
            //如果startIndex + i 没有超出物品的数量, 这个这个格子有物品
            if (startIndex + i >= BagData.Instance.Items.Count)
            {
                //超出了物品的数量,该格子没有物品
                grids[i].UpdateItem(-1, "");
            }
            else
            {
                grids[i].UpdateItem(BagData.Instance.Items[startIndex + i].Id,
                    BagData.Instance.Items[startIndex + i].IconName);
            }
        }
    }
    /// <summary>
    /// 翻页的右按钮
    /// </summary>
    void RightClick()
    {
        //Debug.Log("RightClick");
        //判断是当前页是是最后一页
        if (currentNum < maxNum)
        {
            //不是最后一页
            currentNum++;
            UpdatePanel();//当前页数变了,需要更新一下界面的显示
        }
    }
    /// <summary>
    /// 翻页的左按钮
    /// </summary>
    void LeftClick()
    {
        //Debug.Log("LeftClick");
        //判断当前页数是不是第一页
        if (currentNum > 1)
        {
            currentNum--;
            UpdatePanel();//当前页数变了,需要更新一下界面的显示
        }
    }
    /// <summary>
    /// 整理按钮
    /// </summary>
    void ClearUpClick()
    {
        Debug.Log("ClearUpClick");
        BagController.Instance.ClearUp();
    }
}

GridBase

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.EventSystems;
public class GridBase : MonoBehaviour,
    IPointerEnterHandler,
    IPointerExitHandler,
    IPointerClickHandler,
    IBeginDragHandler,
    IDragHandler,
    IEndDragHandler
{
    public int itemID = -1;// 规定-1  那么这个格子空的
    public Transform tempParent;//拖动时临时的父物体
    private Image image;//显示装备的图片
    private Vector2 outPos;//转换之后的坐标
    private Vector2 offset;//鼠标偏移量
    private RectTransform parentRT;
    protected void Init()
    {
        image = transform.Find("Item").GetComponent<Image>();
        parentRT = tempParent as RectTransform;
    }
    /// <summary>
    /// 更新自己本身的物品
    /// </summary>
    /// <param name="itemID"></param>
    /// <param name="iconName"></param>
    public virtual void UpdateItem(int itemID, string iconName)
    {
        if (this.itemID == itemID && itemID >= 0)
        {
            return;
        }
        this.itemID = itemID;
        if (itemID < 0)//没有物品
        {
            image.enabled = false;
        }
        else
        {
            image.enabled = true;
            if (image.sprite == null || image.sprite.name != iconName)
            {
                Sprite sp = Resources.Load<Sprite>("Texture/Icon/" + iconName);
                image.sprite = sp;
            }
        }
    }
    #region 接口的虚方法
    //开始拖动的虚方法
    protected virtual void BeginDrag(PointerEventData eventData)
    {
        if (itemID < 0) return;
        //Debug.Log("父类:BeginDrag");
        image.transform.parent = tempParent;
        if (RectTransformUtility.ScreenPointToLocalPointInRectangle(parentRT,
            eventData.position, eventData.enterEventCamera, out outPos))
        {
            offset = outPos - new Vector2(image.transform.localPosition.x, image.transform.localPosition.y);
        }
    }
    //拖动的虚方法
    protected virtual void Drag(PointerEventData eventData)
    {
        if (itemID < 0) return;
        //Debug.Log("父类:Drag");
        if (RectTransformUtility.ScreenPointToLocalPointInRectangle(parentRT,
            eventData.position, eventData.enterEventCamera, out outPos))
        {
            image.transform.localPosition = outPos - offset;
        }
    }
    //拖动结束时的虚方法
    protected virtual void EndDrag(PointerEventData eventData)
    {
        if (itemID < 0) return;
        //Debug.Log("父类:EndDrag");
        image.transform.parent = transform;
        image.transform.localPosition = Vector3.zero;
    }
    //点击的虚方法
    protected virtual void Click(PointerEventData eventData)
    {
        //Debug.Log("父类:Click");
    }
    //进入的虚方法
    protected virtual void Enter(PointerEventData eventData)
    {
        //Debug.Log("父类:Enter");
        //Debug.Log("显示信息");
    }
    //出去的虚方法
    protected virtual void Exit(PointerEventData eventData)
    {
        //Debug.Log("父类:Exit");
        //Debug.Log("隐藏信息");
        TipsUI.Instance.HideTips();
    }
    #endregion
    #region 实现的接口
    public void OnBeginDrag(PointerEventData eventData)
    {
        BeginDrag(eventData);
    }
    public void OnDrag(PointerEventData eventData)
    {
        Drag(eventData);
    }
    public void OnEndDrag(PointerEventData eventData)
    {
        EndDrag(eventData);
    }
    public void OnPointerClick(PointerEventData eventData)
    {
        Click(eventData);
    }
    public void OnPointerEnter(PointerEventData eventData)
    {
        Enter(eventData);
    }
    public void OnPointerExit(PointerEventData eventData)
    {
        Exit(eventData);
    }
    #endregion
}

PlayerGridUI

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.EventSystems;
public class PlayerGridUI : GridBase {
    public ItemType gridType;
    private Text text;
       // Use this for initialization
       void Awake () {
        base.Init();
        text = transform.Find("Text").GetComponent<Text>();
        gameObject.tag = "PlayerGrid";
        text.text = ItemData.GetTypeName(gridType);
    }
   
    public override void UpdateItem(int itemID, string iconName)
    {
        base.UpdateItem(itemID, iconName);
        if (itemID >= 0)//有装备
        {
            text.enabled = false;//有装备时,把装备栏的文字隐藏
        }
        else
        {
            text.enabled = true;
        }
    }
    protected override void BeginDrag(PointerEventData eventData)
    {
        if (itemID < 0) return;
        base.BeginDrag(eventData);
        text.enabled = true;//开始拖动时,显示文字
    }
    protected override void Click(PointerEventData eventData)
    {
        if (itemID < 0) return;
        if (eventData.button == PointerEventData.InputButton.Right)
        {
            Debug.Log("卸下: " + itemID);
            BagController.Instance.DemountItem(itemID, CallBck);
        }
    }
    protected override void EndDrag(PointerEventData eventData)
    {
        if (itemID < 0) return;
        base.EndDrag(eventData);
        text.enabled = false;//开始拖动时,显示文字
        if (eventData.pointerCurrentRaycast.gameObject != null &&
            eventData.pointerCurrentRaycast.gameObject.CompareTag("BagGrid"))
        {
            Debug.Log("卸下装备");
            BagController.Instance.DemountItem(itemID, CallBck);
        }
    }
    protected override void Enter(PointerEventData eventData)
    {
        //eventData.dragging 是否处于拖动状态, 鼠标按下,并且再移动
        if (eventData.dragging) return;
        TipsUI.Instance.ShowTips(itemID, TipsUI.ItemGridType.Player, transform.position);
    }
    void CallBck(bool isFinish, string message)
    {
        //暂时测试使用
        if (isFinish)
        {
            Debug.Log("完成了: " + message);
        }
        else
        {
            Debug.LogError(message);
        }
    }
}

BagGridUI

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;
public class BagGridUI : GridBase {
       void Awake () {
        base.Init();
        gameObject.tag = "BagGrid";
    }
    protected override void Click(PointerEventData eventData)
    {
        if (itemID < 0) return;
        if (eventData.button == PointerEventData.InputButton.Right)
        {
            Debug.Log("装备: " + itemID);
            BagController.Instance.EquipmentItem(itemID, BagData.Instance.GetItem(itemID).Type, CallBck);
        }
    }
    protected override void EndDrag(PointerEventData eventData)
    {
        if (itemID < 0) return;
        base.EndDrag(eventData);
        if (eventData.pointerCurrentRaycast.gameObject == null)//当拖出背包区域时
        {
            Debug.Log("卖出物品");
            BagController.Instance.SellItem(itemID, CallBck);
        }
        else if(eventData.pointerCurrentRaycast.gameObject.CompareTag("PlayerGrid"))
        {
            Debug.Log("装备物品");
            //获取到鼠标当前检测到的装备栏的类型
            PlayerGridUI grid = eventData.pointerCurrentRaycast.gameObject.GetComponent<PlayerGridUI>();
            BagController.Instance.EquipmentItem(itemID, grid.gridType, CallBck);
        }
    }
    protected override void Enter(PointerEventData eventData)
    {
        //eventData.dragging 是否处于拖动状态, 鼠标按下,并且再移动
        if (eventData.dragging) return;
        TipsUI.Instance.ShowTips(itemID, TipsUI.ItemGridType.Bag, transform.position);
    }
    void CallBck(bool isFinish, string message)
    {
        //暂时测试使用
        if (isFinish)
        {
            Debug.Log("完成了: " + message);
        }
        else
        {
            Debug.LogError(message);
        }
    }
}

TipsUI

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class TipsUI : MonoBehaviour
{
    private Text nameText;
    private Text typeText;
    private Text atkText;
    private Text defText;
    private Text thumpText;
    private Text hpText;
    private Text mpText;
    private Text angerText;
    private Text weightText;
    private static TipsUI instance;
    public static TipsUI Instance
    {
        get
        {
            /*
            if (null == instance)
            {
                instance = GameObject.Find("Tips").GetComponent<TipsUI>();
            }
            */
            return instance;
        }
    }
    // Use this for initialization
    void Awake()
    {
        instance = this;
        nameText = transform.Find("NameText").GetComponent<Text>();
        typeText = transform.Find("TypeText").GetComponent<Text>();
        atkText = transform.Find("AtkText").GetComponent<Text>();
        defText = transform.Find("DefText").GetComponent<Text>();
        thumpText = transform.Find("ThumpText").GetComponent<Text>();
        hpText = transform.Find("HpText").GetComponent<Text>();
        mpText = transform.Find("MpText").GetComponent<Text>();
        angerText = transform.Find("AngerText").GetComponent<Text>();
        weightText = transform.Find("WeightText").GetComponent<Text>();
    }
    // Update is called once per frame
    void Start()
    {
        gameObject.SetActive(false);
    }
    /// <summary>
    /// 显示物品信息,
    /// </summary>
    /// <param name="id">物品的id</param>
    /// <param name="type">物品在哪</param>
    /// <param name="position">物品的位置</param>
    public void ShowTips(int id, ItemGridType type, Vector3 position)
    {
        ItemData data = null;
        if (type == ItemGridType.Bag)
        {
            data = BagData.Instance.GetItem(id);
        }
        else if (type == ItemGridType.Player)
        {
            data = PlayerData.Instance.GetItem(id);
        }
        if (data != null)
        {
            gameObject.SetActive(true);
            nameText.text = "名字:" + data.ItemName;
            typeText.text = "类型:" + ItemData.GetTypeName(data.Type);
            atkText.text = "攻击力: +" + data.Atk.ToString();
            defText.text = "防御力: +" + data.Def.ToString();
            thumpText.text = "暴击率: +" + data.Thump.ToString();
            hpText.text = "生命值: +" + data.Hp.ToString();
            mpText.text = "魔法值: +" + data.Mp.ToString();
            angerText.text = "怒气值: +" + data.Anger.ToString();
            weightText.text = "负重:" + data.Weight.ToString();
            transform.position = position;
            Vector2 pivot;
            //鼠标偏右
            if (Input.mousePosition.x > Screen.width / 2f)
            {
                pivot.x = 1;
            }
            else
            {
                pivot.x = 0;
            }
            //鼠标偏上
            if (Input.mousePosition.y > Screen.height / 2f)
            {
                pivot.y = 1;
            }
            else
            {
                pivot.y = 0;
            }
            (transform as RectTransform).pivot = pivot;
        }
    }
    /// <summary>
    /// 隐藏属性显示栏
    /// </summary>
    public void HideTips()
    {
        gameObject.SetActive(false);
    }
    public enum ItemGridType
    {
        Bag,
        Player
    }
}
Controller
BagController
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class BagController
{
    #region 单例
    private static BagController instance;
    public static BagController Instance
    {
        get
        {
            if (instance == null)
            {
                instance = new BagController();
            }
            return instance;
        }
    }
    private BagController() { }
    #endregion
    //回调信息
    //第一个参数,是是否完成, 第二个参数, 传递过去的消息
    public delegate void CallBack(bool isFinish, string message);
    #region 处理数据的方法
    /// <summary>
    /// 卖出指定的ID的物品, 规定只能从背包卖
    /// 第二个参数是:当完成或者未完成时,回调调用自己的View中的方法。
    /// </summary>
    /// <param name="id"></param>
    public void SellItem(int id, CallBack callback)
    {
        //通过ID从背包中找到物品
        ItemData data = BagData.Instance.GetItem(id);
        //如果data是null, 背包中没有这个物品,id有问题
        if (data == null)
        {
            //通知调用这个方法的View 你的ID是有问题的吧。
            //Debug.LogError("通知调用这个方法的View 你的ID是有问题的吧。");
            if (callback != null)
            {
                callback(false, "ID有问题!");
            }
        }
        else
        {
            //删除物品
            BagData.Instance.RemoveItem(data);
            if (callback != null)
            {
                callback(true, "卖出成功");
            }
        }
    }
    /// <summary>
    /// 装备物品
    /// </summary>
    /// 参数1: 要装备的物品的ID
    /// 参数2: 要装备的位置
    /// 参数3: View的回调函数(通知View的成功了还是失败)
    public void EquipmentItem(int id, ItemType gridType, CallBack callback)
    {
        //判断ID是否存在
        ItemData bagItem = BagData.Instance.GetItem(id);
        if (bagItem == null)
        {
            //背包里没有这个ID的物品
            if (callback != null)
            {
                callback(false, "背包里没有该ID的物品");
            }
        }
        else
        {
            //如果背包有这个物品,
            //判断该装备类型和你要装备的格子类型是否一致
            if (bagItem.Type == gridType)//装备类型与格子类型一致,可以装备
            {
                //1. 装备栏有物品, 替换
                //2. 装备栏没有物品, 直接装备
                //首先判断装备栏是否有物品
                ItemData playerItem = PlayerData.Instance.GetItem(gridType);
                if (playerItem == null)
                {
                    //证明该格子上没有装备
                    //先把该装备从背包数据里删除
                    BagData.Instance.RemoveItem(bagItem);
                    //再把物品添加到人物数据里
                    PlayerData.Instance.AddItem(bagItem);
                }
                else
                {
                    //证明该格子上有装备
                    //先把人物身上的装备先删除
                    PlayerData.Instance.RemoveItem(playerItem);
                    //再把背包里的装备删除
                    BagData.Instance.RemoveItem(bagItem);
                    //把人物身上的装备添加到背包里
                    BagData.Instance.AddItem(playerItem);
                    //把背包里的装备添加到人物身上
                    PlayerData.Instance.AddItem(bagItem);
                }
                if (callback != null)
                {
                    callback(true, "装备成功");
                }
            }
            else
            {
                if (callback != null)
                {
                    callback(false, "请把装备装到正确的位置");
                }
            }
        }
    }
    /// <summary>
    /// 卸下指定的id的装备,数据一定在playerData里
    /// </summary>
    /// <param name="id"></param>
    /// <param name="callback"></param>
    public void DemountItem(int id, CallBack callback)
    {
        //判断playerData里是否有这个id的装备
        ItemData data = PlayerData.Instance.GetItem(id);
        if (data == null)//空的时候,身上没有这个id的物品
        {
            if (callback != null)
            {
                callback(false, "人物身上没有该ID的物品");
            }
        }
        else
        {
            //先把该装备从人物身上删除
            PlayerData.Instance.RemoveItem(data);
            //再把该装备添加到背包数据里去
            BagData.Instance.AddItem(data);
            //通知界面成功
            if (callback != null)
            {
                callback(true, "成功卸载装备");
            }
        }
    }
    /// <summary>
    /// 整理背包的方法
    /// </summary>
    public void ClearUp()
    {
        BagData.Instance.ItemsSort();
    }
    #endregion
}

LessonListSort

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class LessonListSort : MonoBehaviour {
    List<int> listInt = new List<int>() { 1, 9, 4, 6, 0 };
    List<Obj> listObj = new List<Obj>() { new Obj(1, "小明"), new Obj(2, "小红") };
    // Use this for initialization
    void Start () {
        listInt.Sort(ListIntSort);
        for (int i = 0; i < listInt.Count; i++)
        {
            Debug.Log(listInt[i]);
        }
        listObj.Sort(ListObjSort);
        for (int i = 0; i < listObj.Count; i++)
        {
            Debug.Log(listObj[i].name);
        }
    }
       
       // Update is called once per frame
       void Update () {
              
       }
    int ListIntSort(int a, int b)
    {
        if (a < b)
        {
            return -1;
        }
        else if (a > b)
        {
            return 1;
        }
        else
        {
            return 0;
        }
    }
    public class Obj
    {
        public int id;
        public string name;
        public Obj(int id, string name)
        {
            this.id = id;
            this.name = name;     
        }
    }
    int ListObjSort(Obj a, Obj b)
    {
        if (a.id < b.id)
        {
            return 1;
        }
        else if (a.id > b.id)
        {
            return -1;
        }
        else
        {
            return 0;
        }
    }
}

改格子的枚举

假ID报错

无法再次装备的问题:取消格子里图片和文本的射线检测

整理功能,即列表排序

数值的排序
类对象的排序
List的自定义排序
List.sort(有int返回值,有两个参数List存储类型的参数)
 对于这个方法
Int Sort (T a, T b)
如果返回值是-1,a排在b前
如果返回值是1,b排在a前
如果返回值是,a,b的权重是一致的
枚举转Int,也可比较大
关闭射线检测

猜你喜欢

转载自www.cnblogs.com/ciaowoo/p/10363686.html