Unity3D学习笔记(二十七):MVC框架下的背包系统(2)
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();
}
}
{
"items": [
{
"id": ,
"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":
},
{
"id": ,
"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":
}
],
"atk": 20.0,
"def": 20.0,
"thump": 0.5,
"hp": 100.0,
"mp": 100.0,
"anger": 0.0
}
Bag
{
"items": [
{
"id": ,
"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":
},
{
"id": ,
"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":
},
{
"id": ,
"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":
},
{
"id": ,
"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":
},
{
"id": ,
"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":
},
{
"id": ,
"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":
},
{
"id": ,
"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":
}
],
"maxCapacity": 100.0
}
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,//头饰
}
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 = ; 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 = ; 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 = ;
this.addDef = ;
this.addThump = ;
this.addHp = ;
this.addMp = ;
this.addAnger = ;
//把每一件装备的加成数据加给实际的数据
for (int i = ; 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 = ; 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 = ;
//把每一件装备的负重累加在一起,就是当前的负重
for (int i = ; 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 -;
}
else if (tempA > tempB)
{
return ;
}
else
{
return ;
}
}
}
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 = ; i < grids.Length; i++)
{
grids[i].UpdateItem(-, "");
}
//再把人物身上装备显示在对应的格子上
for (int i = ; i < grids.Length; i++)
{
PlayerGridUI grid = grids[i] as PlayerGridUI;
for (int j = ; 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
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 - ) * grids.Length;//(当前页数 - 1) * 格子数量
//把从起始索引开始,依次的把物品放在对应的格子上
for (int i = ; 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(-, "");
}
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 > )
{
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 那么这个格子空的
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 >= )
{
return;
}
this.itemID = itemID;
if (itemID < )//没有物品
{
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 < ) 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 < ) 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 < ) 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 >= )//有装备
{
text.enabled = false;//有装备时,把装备栏的文字隐藏
}
else
{
text.enabled = true;
}
}
protected override void BeginDrag(PointerEventData eventData)
{
if (itemID < ) return;
base.BeginDrag(eventData);
text.enabled = true;//开始拖动时,显示文字
}
protected override void Click(PointerEventData eventData)
{
if (itemID < ) return;
if (eventData.button == PointerEventData.InputButton.Right)
{
Debug.Log("卸下: " + itemID);
BagController.Instance.DemountItem(itemID, CallBck);
}
}
protected override void EndDrag(PointerEventData eventData)
{
if (itemID < ) 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 < ) 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 < ) 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 = ;
}
else
{
pivot.x = ;
}
//鼠标偏上
if (Input.mousePosition.y > Screen.height / 2f)
{
pivot.y = ;
}
else
{
pivot.y = ;
}
(transform as RectTransform).pivot = pivot;
}
}
/// <summary>
/// 隐藏属性显示栏
/// </summary>
public void HideTips()
{
gameObject.SetActive(false);
}
public enum ItemGridType
{
Bag,
Player
}
}
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>() { , , , , };
List<Obj> listObj = new List<Obj>() { new Obj(, "小明"), new Obj(, "小红") };
// Use this for initialization
void Start () {
listInt.Sort(ListIntSort);
for (int i = ; i < listInt.Count; i++)
{
Debug.Log(listInt[i]);
}
listObj.Sort(ListObjSort);
for (int i = ; 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 -;
}
else if (a > b)
{
return ;
}
else
{
return ;
}
}
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 ;
}
else if (a.id > b.id)
{
return -;
}
else
{
return ;
}
}
}
改格子的枚举
假ID报错
无法再次装备的问题:取消格子里图片和文本的射线检测
整理功能,即列表排序
Unity3D学习笔记(二十七):MVC框架下的背包系统(2)的更多相关文章
- MongoDB学习笔记(三) 在MVC模式下通过Jqgrid表格操作MongoDB数据
看到下图,是通过Jqgrid实现表格数据的基本增删查改的操作.表格数据增删改是一般企业应用系统开发的常见功能,不过不同的是这个表格数据来源是非关系型的数据库MongoDB.nosql虽然概念新颖,但是 ...
- Unity3D学习笔记(二十六):MVC框架下的背包系统(1)
MVC背包 需求: 1.背包格子的装备是可以拖动的 2.装备栏的装备也是可以拖动的 3.当背包格子的装备拖动到装备栏时,如果是装备类型和装备栏类型是一致的能装上 4.背包的装备是按照顺序放在格子中的, ...
- Gin-Go学习笔记二:Gin-Web框架
Gin-Web框架 1> 首先声明,这个是我自己搭建的纯Gin-Web框架,其中有借鉴学习别的想法和代码.已上传到GitHub上.地址为: https://github.com/weiy ...
- Java基础学习笔记二十七 DBUtils和连接池
DBUtils 如果只使用JDBC进行开发,我们会发现冗余代码过多,为了简化JDBC开发,本案例我们讲采用apache commons组件一个成员:DBUtils.DBUtils就是JDBC的简化开发 ...
- Unity3D学习笔记(十七):IK动画、粒子系统和塔防
新动画系统: 反向动力学动画(IK功能): 魔兽世界(头部动画),神秘海域(手部动画),人类一败涂地(手部动画) 如何启用(调整) 1.必须是新动画系统Animator 设置头.手.肘的目标点 2.动 ...
- angular学习笔记(二十七)-$http(5)-使用$http构建RESTful架构
在angular中有一个特别为RESTful架构而定制的服务,是在$http的基础上进行了封装. 但是为了学习,我们先看看用直接$http是如何构建RESTful架构的: 假设有一个银行卡的列表.需要 ...
- Java学习笔记二十七:Java中的抽象类
Java中的抽象类 一:Java抽象类: 在面向对象的概念中,所有的对象都是通过类来描绘的,但是反过来,并不是所有的类都是用来描绘对象的,如果一个类中没有包含足够的信息来描绘一个具体的对象,这样的类就 ...
- PHP学习笔记二十七【重写】
<?php // class Animal{ public $name; protected $price; function cry(){ echo "动物在叫....<br/ ...
- 【工作笔记二】ASP.NET MVC框架下使用MVVM模式
ASP.NET MVC框架下使用MVVM模式 原文:http://www.cnblogs.com/n-pei/archive/2011/07/21/2113022.html 对于asp.net mvc ...
随机推荐
- 【Redis学习之七】Redis持久化
环境 虚拟机:VMware 10 Linux版本:CentOS-6.5-x86_64 客户端:Xshell4 FTP:Xftp4 jdk8 redis-2.8.18 什么是持久化? 将数据从掉电易失的 ...
- impala与hive的比较以及impala的有缺点
最近读的几篇关于impala的文章,这篇良心不错:https://www.biaodianfu.com/impala.html(本文截取部分内容) Impala是Cloudera公司主导开发的新型查询 ...
- Linux基础命令---tracepath追踪路由信息
tracepath tracepath指令可以追踪数据到达目标主机的路由信息,同时还能够发现MTU值.它跟踪路径到目的地,沿着这条路径发现MTU.它使用UDP端口或一些随机端口.它类似于Tracero ...
- bzoj2049 [Sdoi2008]Cave 洞穴勘测 link cut tree入门
link cut tree入门题 首先说明本人只会写自底向上的数组版(都说了不写指针.不写自顶向下QAQ……) 突然发现link cut tree不难写... 说一下各个函数作用: bool isro ...
- 3、CentOS 6.5系统安装配置Tomcat 8详细过程
安装环境:CentOS-6.5 安装方式:源码安装 软件:apache-tomcat-8.0.0.RC3.tar.gz 安装前提 安装tomcat 将apache-tomcat-8.0.0.RC3.t ...
- @Entity 和 @Table
Java Persistence API定义了一种定义,可以将常规的普通Java对象(有时被称作POJO)映射到数据库.这些普通Java对象被称作Entity Bean.除了是用Java Persis ...
- 怎样从外网访问内网IIS?
本地安装了一个IIS,只能在局域网内访问,怎样从外网也能访问到本地的IIS呢?本文将介绍具体的实现步骤. 准备工作 安装并启动IIS 默认安装的IIS端口是80. 实现步骤 下载并解压holer软件包 ...
- @RefreshScope 的作用
让在application.properties里自定义的变量也能通过@Value 注解正常注入
- jQuery获取子元素个数的方法
//获取id=div1下的子元素的个数 $('#id').children().length; //获取id=div1下的p元素个数 $('#id').children('p').length;
- 计算概论(A)/基础编程练习2(8题)/7:整数的个数
#include<stdio.h> int main() { ] = {}; // 输入k个正整数 scanf("%d",&k); // 循环读入和进行算术 w ...