整个背包系统的系统图

最后效果图:

层级面板:

在这里用到了资源商店的一个解析Json的插件,找一个免费的就行。

资源面板:

下面来介绍代码。

物品基类。

这个类是所有物品的基类,里面定义了一些属性,这些属性是所有物品都共有的,所有
把他们抽象出来,里面还有2个构造方法、2个结构体和一个显示提示信息的方法。using UnityEngine;
using System.Collections;/// <summary>
/// 物品基类
/// </summary>
public class Item  {public int ID { get; set; }public string Name { get; set; }public ItemType Type { get; set; }public ItemQuality Quality { get; set; }public string Description { get; set; }public int Capacity { get; set; }public int BuyPrice { get; set; }public int SellPrice { get; set; }public string Sprite { get; set; }public Item(){this.ID = -1;}public Item(int id, string name, ItemType type, ItemQuality quality, string des, int capacity, int buyPrice, int sellPrice,string sprite){this.ID = id;this.Name = name;this.Type = type;this.Quality = quality;this.Description = des;this.Capacity = capacity;this.BuyPrice = buyPrice;this.SellPrice = sellPrice;this.Sprite = sprite;}/// <summary>/// 物品类型/// </summary>public enum ItemType{Consumable,//消耗品Equipment,//装备Weapon,//武器Material//材料}/// <summary>/// 品质/// </summary>public enum ItemQuality{Common,//一般Uncommon,//非一般Rare,//稀有的Epic,//史诗Legendary,//传说Artifact//人造物品}/// <summary> /// 得到提示面板应该显示什么样的内容/// </summary>/// <returns></returns>public virtual string GetToolTipText(){string color = "";switch (Quality){case ItemQuality.Common:color = "white";break;case ItemQuality.Uncommon:color = "lime";break;case ItemQuality.Rare:color = "navy";break;case ItemQuality.Epic:color = "magenta";break;case ItemQuality.Legendary:color = "orange";break;case ItemQuality.Artifact:color = "red";break;}string text = string.Format("<color={4}>{0}</color>\n<size=10><color=green>购买价格:{1} 出售价格:{2}</color></size>\n<color=yellow><size=10>{3}</size></color>", Name, BuyPrice, SellPrice, Description, color);return text;}
}

下面是消耗品类,继承物品基类。

using UnityEngine;
using System.Collections;
/// <summary>
/// 消耗品类
/// </summary>
public class Consumable : Item {public int HP { get; set; }public int MP { get; set; }public Consumable(int id, string name, ItemType type, ItemQuality quality, string des, int capacity, int buyPrice, int sellPrice ,string sprite,int hp,int mp):base(id,name,type,quality,des,capacity,buyPrice,sellPrice,sprite){this.HP = hp;this.MP = mp;}public override string GetToolTipText(){string text = base.GetToolTipText();string newText = string.Format("{0}\n\n<color=blue>加血:{1}\n加蓝:{2}</color>", text, HP, MP);return newText;}public override string ToString(){string s = "";s += ID.ToString();s += Type;s += Quality;s += Description;s += Capacity; s += BuyPrice;s += SellPrice;s += Sprite;s += HP;s += MP;return s;}}

下面是装备类,继承物品基类。

using UnityEngine;
using System.Collections;public class Equipment : Item {/// <summary>/// 力量/// </summary>public int Strength { get; set; }/// <summary>/// 智力/// </summary>public int Intellect { get; set; }/// <summary>/// 敏捷/// </summary>public int Agility { get; set; }/// <summary>/// 体力/// </summary>public int Stamina { get; set; }/// <summary>/// 装备类型/// </summary>public EquipmentType EquipType { get; set; }public Equipment(int id, string name, ItemType type, ItemQuality quality, string des, int capacity, int buyPrice, int sellPrice,string sprite,int strength,int intellect,int agility,int stamina,EquipmentType equipType): base(id, name, type, quality, des, capacity, buyPrice, sellPrice,sprite){this.Strength = strength;this.Intellect = intellect;this.Agility = agility;this.Stamina = stamina;this.EquipType = equipType;}/// <summary>/// 装备类型/// </summary>public enum EquipmentType{None,Head,Neck,Chest,Ring,Leg,Bracer,Boots,Shoulder,Belt,OffHand}public override string GetToolTipText(){string text = base.GetToolTipText();string equipTypeText = "";switch (EquipType){case EquipmentType.Head:equipTypeText="头部";break;case EquipmentType.Neck:equipTypeText="脖子";break;case EquipmentType.Chest:equipTypeText="胸部";break;case EquipmentType.Ring:equipTypeText="戒指";break;case EquipmentType.Leg:equipTypeText="腿部";break;case EquipmentType.Bracer:equipTypeText="护腕";break;case EquipmentType.Boots:equipTypeText="靴子";break;case EquipmentType.Shoulder:equipTypeText="护肩";break;case EquipmentType.Belt:equipTypeText = "腰带";break;case EquipmentType.OffHand:equipTypeText="副手";break;}string newText = string.Format("{0}\n\n<color=blue>装备类型:{1}\n力量:{2}\n智力:{3}\n敏捷:{4}\n体力:{5}</color>", text,equipTypeText,Strength,Intellect,Agility,Stamina);return newText;}
}

下面是武器类,继承物品基类。

using UnityEngine;
using System.Collections;/// <summary>
/// 武器
/// </summary>
public class Weapon : Item {public int Damage { get; set; }public WeaponType WpType { get; set; }public Weapon(int id, string name, ItemType type, ItemQuality quality, string des, int capacity, int buyPrice, int sellPrice,string sprite,int damage,WeaponType wpType): base(id, name, type, quality, des, capacity, buyPrice, sellPrice,sprite){this.Damage = damage;this.WpType = wpType;}/// <summary>/// 武器类型/// </summary>public enum WeaponType{None,OffHand,MainHand}public override string GetToolTipText(){string text = base.GetToolTipText();string wpTypeText = "";switch (WpType){case WeaponType.OffHand:wpTypeText = "副手";break;case WeaponType.MainHand:wpTypeText = "主手";break;}string newText = string.Format("{0}\n\n<color=blue>武器类型:{1}\n攻击力:{2}</color>", text, wpTypeText, Damage);return newText;}
}

下面是材料类,继承物品基类。

using UnityEngine;
using System.Collections;/// <summary>
/// 材料类
/// </summary>
public class Material : Item {public Material(int id, string name, ItemType type, ItemQuality quality, string des, int capacity, int buyPrice, int sellPrice,string sprite): base(id, name, type, quality, des, capacity, buyPrice, sellPrice,sprite){}
}

记录装备信息的Json。

[{"id": 1,"name": "血瓶","type": "Consumable","quality": "Common","description": "这个是用来加血的","capacity": 10,"buyPrice": 10,"sellPrice": 5,"hp": 10,"mp": 0,"sprite": "Sprites/Items/hp"},{"id": 2,"name": "蓝瓶","type": "Consumable","quality": "Common","description": "这个是用来加蓝的","capacity": 10,"buyPrice": 10,"sellPrice": 5,"hp": 0,"mp": 10,"sprite": "Sprites/Items/mp"},{"id": 3,"name": "胸甲","type": "Equipment","quality": "Rare","description": "这个胸甲很牛B","capacity": 1,"buyPrice": 20,"sellPrice": 10,"sprite": "Sprites/Items/armor","strength":10,"intellect":4,"agility":9,"stamina":1,"equipType":"Chest"},{"id": 4,"name": "皮腰带","type": "Equipment","quality": "Epic","description": "这个腰带可以加速","capacity": 1,"buyPrice": 20,"sellPrice": 10,"sprite": "Sprites/Items/belts","strength":1,"intellect":6,"agility":10,"stamina":10,"equipType":"Belt"},{"id": 5,"name": "靴子","type": "Equipment","quality": "Legendary","description": "这个靴子可以加速","capacity": 1,"buyPrice": 20,"sellPrice": 10,"sprite": "Sprites/Items/boots","strength":10,"intellect":5,"agility":0,"stamina":10,"equipType":"Boots"},{"id": 6,"name": "护腕","type": "Equipment","quality": "Rare","description": "这个护腕可以增加防御","capacity": 1,"buyPrice": 20,"sellPrice": 10,"sprite": "Sprites/Items/bracers","strength":1,"intellect":2,"agility":3,"stamina":4,"equipType":"Bracer"},{"id": 7,"name": "神启手套","type": "Equipment","quality": "Common","description": "很厉害的手套","capacity": 1,"buyPrice": 10,"sellPrice": 5,"sprite": "Sprites/Items/gloves","strength":2,"intellect":3,"agility":4,"stamina":4,"equipType":"OffHand"},{"id": 8,"name": "头盔","type": "Equipment","quality": "Artifact","description": "很厉害的头盔","capacity": 1,"buyPrice": 10,"sellPrice": 5,"sprite": "Sprites/Items/helmets","strength":2,"intellect":3,"agility":4,"stamina":4,"equipType":"Head"},{"id": 9,"name": "项链","type": "Equipment","quality": "Rare","description": "很厉害的项链","capacity": 1,"buyPrice": 10,"sellPrice": 5,"sprite": "Sprites/Items/necklace","strength":2,"intellect":3,"agility":4,"stamina":4,"equipType":"Neck"},{"id": 10,"name": "戒指","type": "Equipment","quality": "Common","description": "很厉害的戒指","capacity": 1,"buyPrice": 20,"sellPrice": 20,"sprite": "Sprites/Items/rings","strength":20,"intellect":3,"agility":4,"stamina":4,"equipType":"Ring"},{"id": 11,"name": "裤子","type": "Equipment","quality": "Uncommon","description": "很厉害的裤子","capacity": 1,"buyPrice": 40,"sellPrice": 20,"sprite": "Sprites/Items/pants","strength":20,"intellect":30,"agility":40,"stamina":40,"equipType":"Leg"},{"id": 12,"name": "护肩","type": "Equipment","quality": "Legendary","description": "很厉害的护肩","capacity": 1,"buyPrice": 100,"sellPrice": 20,"sprite": "Sprites/Items/shoulders","strength":2,"intellect":3,"agility":4,"stamina":4,"equipType":"Shoulder"},{"id": 13,"name": "开天斧","type": "Weapon","quality": "Rare","description": "渔翁移山用的斧子","capacity": 1,"buyPrice": 50,"sellPrice": 20,"sprite": "Sprites/Items/axe","damage":100,"weaponType":"MainHand"},{"id": 14,"name": "阴阳剑","type": "Weapon","quality": "Rare","description": "非常厉害的剑","capacity": 1,"buyPrice": 15,"sellPrice": 5,"sprite": "Sprites/Items/sword","damage":20,"weaponType":"OffHand"},{"id": 15,"name": "开天斧的锻造秘籍","type": "Material","quality": "Artifact","description": "用来锻造开天斧的秘籍","capacity": 2,"buyPrice": 100,"sellPrice": 99,"sprite": "Sprites/Items/book"},{"id": 16,"name": "头盔的锻造秘籍","type": "Material","quality": "Common","description": "用来锻造头盔的秘籍","capacity": 2,"buyPrice": 50,"sellPrice": 10,"sprite": "Sprites/Items/scroll"},{"id": 17,"name": "铁块","type": "Material","quality": "Common","description": "用来锻造其他东西的必备材料","capacity": 20,"buyPrice": 5,"sellPrice": 4,"sprite": "Sprites/Items/ingots"}
]

锻造Json。

[
{
"Item1ID":15,
"Item1Amount":1,
"Item2ID":17,
"Item2Amount":2,
"ResID":13
},
{
"Item1ID":16,
"Item1Amount":1,
"Item2ID":17,
"Item2Amount":5,
"ResID":8
}
]

管理类。

using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using UnityEngine.UI;/// <summary>
/// 这个类主要是起到管理的作用
/// </summary>
public class InventoryManager : MonoBehaviour
{#region 单例模式private static InventoryManager _instance;public static InventoryManager Instance{get{if (_instance == null){//下面的代码只会执行一次_instance = GameObject.Find("InventoryManager").GetComponent<InventoryManager>();}return _instance;}}#endregion/// <summary>///  物品信息的列表(集合)/// </summary>private List<Item> itemList;#region ToolTipprivate ToolTip toolTip;private bool isToolTipShow = false;//偏移位置private Vector2 toolTipPosionOffset = new Vector2(10, -10);#endregionprivate Canvas canvas;#region PickedItem 是否选中物品private bool isPickedItem = false;public bool IsPickedItem{get{return isPickedItem;}}private ItemUI pickedItem;//鼠标选中的物体public ItemUI PickedItem{get{return pickedItem;}}#endregionvoid Awake(){//解析JsonParseItemJson();}void Start(){toolTip = GameObject.FindObjectOfType<ToolTip>();canvas = GameObject.Find("Canvas").GetComponent<Canvas>();pickedItem = GameObject.Find("PickedItem").GetComponent<ItemUI>();pickedItem.Hide();}void Update(){if (isPickedItem){//如果我们捡起了物品,我们就要让物品跟随鼠标Vector2 position;//获得UI坐标RectTransformUtility.ScreenPointToLocalPointInRectangle(canvas.transform as RectTransform, Input.mousePosition, null, out position);pickedItem.SetLocalPosition(position);}else if (isToolTipShow){//控制提示面板跟随鼠标Vector2 position;RectTransformUtility.ScreenPointToLocalPointInRectangle(canvas.transform as RectTransform, Input.mousePosition, null, out position);toolTip.SetLocalPotion(position+toolTipPosionOffset);}//物品丢弃的处理if (isPickedItem && Input.GetMouseButtonDown(0) && UnityEngine.EventSystems.EventSystem.current.IsPointerOverGameObject(-1)==false)//判断是否点击到UI{isPickedItem = false;PickedItem.Hide();}}/// <summary>/// 解析物品信息/// </summary>void ParseItemJson(){itemList = new List<Item>();//文本为在Unity里面是 TextAsset类型TextAsset itemText = Resources.Load<TextAsset>("Items");string itemsJson = itemText.text;//物品信息的Json格式JSONObject j = new JSONObject(itemsJson);foreach (JSONObject temp in j.list){string typeStr = temp["type"].str;Item.ItemType type= (Item.ItemType)System.Enum.Parse(typeof(Item.ItemType), typeStr);//字符串转换为枚举//下面的是解析这个对象里面的公有属性int id = (int)(temp["id"].n);string name = temp["name"].str;Item.ItemQuality quality = (Item.ItemQuality)System.Enum.Parse(typeof(Item.ItemQuality), temp["quality"].str);string description = temp["description"].str;int capacity = (int)(temp["capacity"].n);int buyPrice = (int)(temp["buyPrice"].n);int sellPrice = (int)(temp["sellPrice"].n);string sprite = temp["sprite"].str;Item item = null; switch (type){case Item.ItemType.Consumable:int hp = (int)(temp["hp"].n);int mp = (int)(temp["mp"].n);item = new Consumable(id, name, type, quality, description, capacity, buyPrice, sellPrice, sprite, hp, mp);break;case Item.ItemType.Equipment:int strength = (int)temp["strength"].n;int intellect = (int)temp["intellect"].n;int agility = (int)temp["agility"].n;int stamina = (int)temp["stamina"].n;Equipment.EquipmentType equipType = (Equipment.EquipmentType) System.Enum.Parse( typeof(Equipment.EquipmentType),temp["equipType"].str );item = new Equipment(id, name, type, quality, description, capacity, buyPrice, sellPrice, sprite, strength, intellect, agility, stamina, equipType);break;case Item.ItemType.Weapon:int damage = (int) temp["damage"].n;Weapon.WeaponType wpType = (Weapon.WeaponType)System.Enum.Parse(typeof(Weapon.WeaponType), temp["weaponType"].str);item = new Weapon(id, name, type, quality, description, capacity, buyPrice, sellPrice, sprite, damage, wpType);break;case Item.ItemType.Material:item = new Material(id, name, type, quality, description, capacity, buyPrice, sellPrice, sprite);break;}itemList.Add(item);//将解析得到的物品放入物品集合}}/// <summary>/// 通过ID得到物品/// </summary>/// <param name="id"></param>/// <returns></returns>public Item GetItemById(int id){foreach (Item item in itemList){if (item.ID == id){return item;}}return null;}/// <summary>/// 显示提示信息/// </summary>/// <param name="content"></param>public void ShowToolTip(string content){if (this.isPickedItem) return;isToolTipShow = true;toolTip.Show(content);}/// <summary>/// 隐藏提示信息/// </summary>public void HideToolTip(){isToolTipShow = false;toolTip.Hide();}/// <summary>/// 捡起物品槽指定数量的物品/// </summary>/// <param name="item"></param>/// <param name="amount"></param>public void PickupItem(Item item,int amount){PickedItem.SetItem(item, amount);isPickedItem = true;PickedItem.Show();this.toolTip.Hide();//如果我们捡起了物品,我们就要让物品跟随鼠标Vector2 position;RectTransformUtility.ScreenPointToLocalPointInRectangle(canvas.transform as RectTransform, Input.mousePosition, null, out position);pickedItem.SetLocalPosition(position);}/// <summary>/// 从手上拿掉一个物品放在物品槽里面/// </summary>public void RemoveItem(int amount=1){PickedItem.ReduceAmount(amount);if (PickedItem.Amount <= 0){isPickedItem = false;PickedItem.Hide();}}/// <summary>/// 保存物品/// </summary>public void SaveInventory(){Knapsack.Instance.SaveInventory();Chest.Instance.SaveInventory();CharacterPanel.Instance.SaveInventory();Forge.Instance.SaveInventory();PlayerPrefs.SetInt("CoinAmount", GameObject.FindGameObjectWithTag("Player").GetComponent<Player>().CoinAmount);}/// <summary>/// 加载物品/// </summary>public void LoadInventory(){Knapsack.Instance.LoadInventory();Chest.Instance.LoadInventory();CharacterPanel.Instance.LoadInventory();Forge.Instance.LoadInventory();if (PlayerPrefs.HasKey("CoinAmount")){GameObject.FindGameObjectWithTag("Player").GetComponent<Player>().CoinAmount = PlayerPrefs.GetInt("CoinAmount");}}}

处理物品的类。

using UnityEngine;
using System.Collections;
using UnityEngine.UI;public class ItemUI : MonoBehaviour
{#region Data 物品和数量public Item Item { get; private set; }public int Amount { get; private set; }#endregion#region UI Component 物品显示类型和数量private Image itemImage;private Text amountText;private Image ItemImage{get{if (itemImage == null){itemImage = GetComponent<Image>();}return itemImage;}}private Text AmountText{get{if (amountText == null){amountText = GetComponentInChildren<Text>();}return amountText;}}#endregion#region UI动画private float targetScale = 1f;private Vector3 animationScale = new Vector3(1.4f, 1.4f, 1.4f);private float smoothing = 4;void Update(){if (transform.localScale.x != targetScale){//动画float scale = Mathf.Lerp(transform.localScale.x, targetScale,smoothing*Time.deltaTime);transform.localScale = new Vector3(scale, scale, scale);if (Mathf.Abs(transform.localScale.x - targetScale) < .02f){transform.localScale = new Vector3(targetScale, targetScale, targetScale);}}}#endregion/// <summary>/// 设置物品/// </summary>/// <param name="item"></param>/// <param name="amount"></param>public void SetItem(Item item,int amount = 1){transform.localScale = animationScale;this.Item = item;this.Amount = amount;// update ui ItemImage.sprite = Resources.Load<Sprite>(item.Sprite);if (Item.Capacity > 1)AmountText.text = Amount.ToString();elseAmountText.text = "";}/// <summary>/// 增加物品数量/// </summary>/// <param name="amount"></param>public void AddAmount(int amount=1){transform.localScale = animationScale;this.Amount += amount;//update ui if (Item.Capacity > 1)AmountText.text = Amount.ToString();elseAmountText.text = "";}/// <summary>/// 减少物品数量/// </summary>/// <param name="amount"></param>public void ReduceAmount(int amount = 1){transform.localScale = animationScale;this.Amount -= amount;//update ui if (Item.Capacity > 1)AmountText.text = Amount.ToString();elseAmountText.text = "";}/// <summary>/// 设置物品数量/// </summary>/// <param name="amount"></param>public void SetAmount(int amount){transform.localScale = animationScale;this.Amount = amount;//update ui if (Item.Capacity > 1)AmountText.text = Amount.ToString();elseAmountText.text = "";}/// <summary>/// 当前物品跟另一个物品交换显示/// </summary>/// <param name="itemUI"></param>public void Exchange(ItemUI itemUI){Item itemTemp = itemUI.Item;int amountTemp = itemUI.Amount;itemUI.SetItem(this.Item, this.Amount);this.SetItem(itemTemp, amountTemp);}/// <summary>/// 显示物品/// </summary>public void Show(){gameObject.SetActive(true);}/// <summary>/// 隐藏物品/// </summary>public void Hide(){gameObject.SetActive(false);}/// <summary>/// 设置局部坐标位置/// </summary>/// <param name="position"></param>public void SetLocalPosition(Vector3 position){transform.localPosition = position;}}

提示信息类。

using UnityEngine;
using System.Collections;
using UnityEngine.UI;/// <summary>
/// 这个类主要用来控制提示信息的
/// </summary>
public class ToolTip : MonoBehaviour {private Text toolTipText;private Text contentText;private CanvasGroup canvasGroup;private float targetAlpha = 0 ;public float smoothing = 1;void Start(){toolTipText = GetComponent<Text>();contentText = transform.Find("Content").GetComponent<Text>();canvasGroup = GetComponent<CanvasGroup>();}void Update(){if (canvasGroup.alpha != targetAlpha){canvasGroup.alpha = Mathf.Lerp(canvasGroup.alpha, targetAlpha,smoothing*Time.deltaTime);if (Mathf.Abs(canvasGroup.alpha - targetAlpha) < 0.01f){canvasGroup.alpha = targetAlpha;}}}/// <summary>/// 显示提示信息/// </summary>/// <param name="text"></param>public void Show(string text){toolTipText.text = text;contentText.text = text;targetAlpha = 1;}/// <summary>/// 隐藏提示信息/// </summary>public void Hide(){targetAlpha = 0;}/// <summary>/// 设置局部坐标位置/// </summary>/// <param name="position"></param>public void SetLocalPotion(Vector3 position){transform.localPosition = position;}}

物品槽类。

using UnityEngine;
using System.Collections;
using UnityEngine.EventSystems;/// <summary>
/// 物品槽
/// </summary>
public class Slot : MonoBehaviour ,IPointerEnterHandler,IPointerExitHandler,IPointerDownHandler{public GameObject itemPrefab;/// <summary>/// 把item放在自身下面/// 如果自身下面已经有item了,amount++/// 如果没有 根据itemPrefab去实例化一个item,放在下面/// </summary>/// <param name="item"></param>public void StoreItem(Item item){if (transform.childCount == 0){GameObject itemGameObject = Instantiate(itemPrefab) as GameObject;itemGameObject.transform.SetParent(this.transform);itemGameObject.transform.localScale = Vector3.one;itemGameObject.transform.localPosition = Vector3.zero;itemGameObject.GetComponent<ItemUI>().SetItem(item);}else{transform.GetChild(0).GetComponent<ItemUI>().AddAmount();}}/// <summary>/// 得到当前物品槽存储的物品类型/// </summary>/// <returns></returns>public Item.ItemType GetItemType(){return transform.GetChild(0).GetComponent<ItemUI>().Item.Type;}/// <summary>/// 得到物品的id/// </summary>/// <returns></returns>public int GetItemId(){return transform.GetChild(0).GetComponent<ItemUI>().Item.ID;}/// <summary>/// 判断物品槽是否满了/// </summary>/// <returns></returns>public bool IsFilled(){ItemUI itemUI = transform.GetChild(0).GetComponent<ItemUI>();return itemUI.Amount >= itemUI.Item.Capacity;//当前的数量大于等于容量}/// <summary>/// 鼠标移出,隐藏提示信息/// </summary>/// <param name="eventData"></param>public void OnPointerExit(PointerEventData eventData){if(transform.childCount>0)InventoryManager.Instance.HideToolTip();}/// <summary>/// 鼠标移入,显示提示信息/// </summary>/// <param name="eventData"></param>public void OnPointerEnter(PointerEventData eventData){if (transform.childCount > 0){string toolTipText = transform.GetChild(0).GetComponent<ItemUI>().Item.GetToolTipText();InventoryManager.Instance.ShowToolTip(toolTipText);}}/// <summary>/// 鼠标按下/// </summary>/// <param name="eventData"></param>public virtual void OnPointerDown(PointerEventData eventData){//右键装备物品if (eventData.button == PointerEventData.InputButton.Right)//按下右键{if (InventoryManager.Instance.IsPickedItem==false && transform.childCount > 0)//手上没有物品,物品槽有物品{ItemUI currentItemUI = transform.GetChild(0).GetComponent<ItemUI>();//得到物品槽物品if (currentItemUI.Item is Equipment || currentItemUI.Item is Weapon)//如果是装备或武器{currentItemUI.ReduceAmount(1);Item currentItem = currentItemUI.Item;if (currentItemUI.Amount <= 0){DestroyImmediate(currentItemUI.gameObject);InventoryManager.Instance.HideToolTip();}CharacterPanel.Instance.PutOn(currentItem);   //将物品装备到角色上}}}//如果没有按下左键就什么也不做if (eventData.button != PointerEventData.InputButton.Left) return;// 自身是空 1,IsPickedItem ==true  pickedItem放在这个位置// 按下ctrl      放置当前鼠标上的物品的一个// 没有按下ctrl   放置当前鼠标上的物品的所有//2,IsPickedItem==false  不做任何处理// 自身不是空 //1,IsPickedItem==true//自身的id==pickedItem.id  // 按下ctrl      放置当前鼠标上的物品的一个// 没有按下ctrl   放置当前鼠标上的物品的所有//可以完全放下//只能放下其中一部分//自身的id!=pickedItem.id   pickedItem跟当前物品交换          //2,IsPickedItem==false//ctrl按下 取得当前物品槽中物品的一半//ctrl没有按下 把当前物品槽里面的物品放到鼠标上if (transform.childCount > 0)//物品槽有物品{ItemUI currentItem = transform.GetChild(0).GetComponent<ItemUI>();if (InventoryManager.Instance.IsPickedItem == false)//当前没有选中任何物品( 当前手上没有任何物品)当前鼠标上没有任何物品{if (Input.GetKey(KeyCode.LeftControl)){int amountPicked = (currentItem.Amount + 1) / 2;//选中一半InventoryManager.Instance.PickupItem(currentItem.Item, amountPicked);int amountRemained = currentItem.Amount - amountPicked;//剩余物品if (amountRemained <= 0){Destroy(currentItem.gameObject);//销毁当前物品}else{currentItem.SetAmount(amountRemained);//重新调整物品数量}}else//全部选中{InventoryManager.Instance.PickupItem(currentItem.Item,currentItem.Amount);Destroy(currentItem.gameObject);//销毁当前物品}}else//手上有物品{//1,IsPickedItem==true//自身的id==pickedItem.id  // 按下ctrl      放置当前鼠标上的物品的一个// 没有按下ctrl   放置当前鼠标上的物品的所有//可以完全放下//只能放下其中一部分//自身的id!=pickedItem.id   pickedItem跟当前物品交换          if (currentItem.Item.ID == InventoryManager.Instance.PickedItem.Item.ID){if (Input.GetKey(KeyCode.LeftControl)){if (currentItem.Item.Capacity > currentItem.Amount)//当前物品槽还有容量{currentItem.AddAmount();//物品槽物品加一InventoryManager.Instance.RemoveItem();//手上物品减一}else//物品槽没有容量{return;}}else{if (currentItem.Item.Capacity > currentItem.Amount){int amountRemain = currentItem.Item.Capacity - currentItem.Amount;//当前物品槽剩余的空间if (amountRemain >= InventoryManager.Instance.PickedItem.Amount){currentItem.SetAmount(currentItem.Amount + InventoryManager.Instance.PickedItem.Amount);//物品槽更新容量InventoryManager.Instance.RemoveItem(InventoryManager.Instance.PickedItem.Amount);//移除手上全部物品}else{currentItem.SetAmount(currentItem.Amount + amountRemain);//物品槽放满InventoryManager.Instance.RemoveItem(amountRemain);//手上物品减去物品槽剩余容量。}}//物品槽满了else{return;}}}else{Item item = currentItem.Item;int amount = currentItem.Amount;currentItem.SetItem(InventoryManager.Instance.PickedItem.Item, InventoryManager.Instance.PickedItem.Amount);InventoryManager.Instance.PickedItem.SetItem(item, amount);}}}//物品槽没有物品else{// 自身是空  //1,IsPickedItem ==true  pickedItem放在这个位置// 按下ctrl      放置当前鼠标上的物品的一个// 没有按下ctrl   放置当前鼠标上的物品所有数量//2,IsPickedItem==false  不做任何处理if (InventoryManager.Instance.IsPickedItem == true){if (Input.GetKey(KeyCode.LeftControl)){this.StoreItem(InventoryManager.Instance.PickedItem.Item);InventoryManager.Instance.RemoveItem();//从手上放一次放一个物品到物品槽}else//将手上物品全部放入物品槽,直到放不下。{for (int i = 0; i < InventoryManager.Instance.PickedItem.Amount; i++){this.StoreItem(InventoryManager.Instance.PickedItem.Item);}InventoryManager.Instance.RemoveItem(InventoryManager.Instance.PickedItem.Amount);}}//手上也没有物品else{return;}}}
}

装备槽类。

using UnityEngine;
using System.Collections;
using UnityEngine.EventSystems;/// <summary>
/// 装备槽,用来放入装备
/// </summary>
public class EquipmentSlot : Slot {//装备类型public Equipment.EquipmentType equipType;//武器类型public Weapon.WeaponType wpType;public override void OnPointerDown(UnityEngine.EventSystems.PointerEventData eventData){//角色装备槽按下左键卸载装备到背包if (eventData.button == PointerEventData.InputButton.Right){if (InventoryManager.Instance.IsPickedItem == false && transform.childCount > 0){ItemUI currentItemUI = transform.GetChild(0).GetComponent<ItemUI>();Item itemTemp = currentItemUI.Item;DestroyImmediate(currentItemUI.gameObject);//脱掉放到背包里面transform.parent.SendMessage("PutOff", itemTemp);InventoryManager.Instance.HideToolTip();}}//没有按下左键什么也不做if (eventData.button != PointerEventData.InputButton.Left) return;// 手上有 东西//当前装备槽 有装备//无装备// 手上没 东西//当前装备槽 有装备 //无装备  不做处理bool isUpdateProperty = false;if (InventoryManager.Instance.IsPickedItem == true){//手上有东西的情况ItemUI pickedItem = InventoryManager.Instance.PickedItem;if (transform.childCount > 0)//物品槽有物品{ItemUI currentItemUI  = transform.GetChild(0).GetComponent<ItemUI>();//当前装备槽里面的物品if( IsRightItem(pickedItem.Item) ){InventoryManager.Instance.PickedItem.Exchange(currentItemUI);//交换物品isUpdateProperty = true;}}else//物品槽没有物品{if (IsRightItem(pickedItem.Item)){this.StoreItem(InventoryManager.Instance.PickedItem.Item);//物品放入物品槽InventoryManager.Instance.RemoveItem(1);isUpdateProperty = true;}}}else//手上没有物品{//手上没东西的情况if (transform.childCount > 0){ItemUI currentItemUI = transform.GetChild(0).GetComponent<ItemUI>();InventoryManager.Instance.PickupItem(currentItemUI.Item, currentItemUI.Amount);Destroy(currentItemUI.gameObject);isUpdateProperty = true;}}if (isUpdateProperty)//更新属性面板信息{transform.parent.SendMessage("UpdatePropertyText");}}//判断item是否适合放在这个位置public bool IsRightItem(Item item){if ((item is Equipment && ((Equipment)(item)).EquipType == this.equipType) ||(item is Weapon && ((Weapon)(item)).WpType == this.wpType)){return true;}return false;}
}

锻造类

using UnityEngine;
using System.Collections;
using System.Collections.Generic;/// <summary>
/// 锻造类
/// </summary>
public class Formula  {public int Item1ID { get;private set; }public int Item1Amount { get;private set; }public int Item2ID { get;private set; }public int Item2Amount { get;private set; }public int ResID { get;private set; }//锻造结果的物品 private List<int> needIdList = new List<int>();//所需要的物品的idpublic List<int> NeedIdList{get{return needIdList;}}public Formula(int item1ID, int item1Amount, int item2ID, int item2Amount, int resID){this.Item1ID = item1ID;this.Item1Amount = item1Amount;this.Item2ID = item2ID;this.Item2Amount = item2Amount;this.ResID = resID;for (int i = 0; i < Item1Amount; i++){needIdList.Add(Item1ID);}for (int i = 0; i < Item2Amount; i++){needIdList.Add(Item2ID);}}/// <summary>/// 判断是否可以锻造/// </summary>/// <param name="idList"></param>/// <returns></returns>public bool Match(List<int> idList )//提供的物品的id{List<int> tempIDList = new List<int>(idList);foreach(int id in needIdList){bool isSuccess = tempIDList.Remove(id);if (isSuccess == false){return false;}}return true;}
}

物品买卖类。

using UnityEngine;
using System.Collections;
using UnityEngine.EventSystems;/// <summary>
/// 买卖物品
/// </summary>
public class VendorSlot : Slot {public override void OnPointerDown(UnityEngine.EventSystems.PointerEventData eventData){if (eventData.button == PointerEventData.InputButton.Right &&InventoryManager.Instance.IsPickedItem==false ){if (transform.childCount > 0){Item currentItem = transform.GetChild(0).GetComponent<ItemUI>().Item;transform.parent.parent.SendMessage("BuyItem", currentItem);}}else if (eventData.button == PointerEventData.InputButton.Left && InventoryManager.Instance.IsPickedItem == true){transform.parent.parent.SendMessage("SellItem");}}
}

存储基类

using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System;
using System.Text;/// <summary>
/// 存储类,其他面板类都继承他
/// </summary>
public class Inventory : MonoBehaviour {protected Slot[] slotList;private float targetAlpha = 1;private float smoothing = 4;private CanvasGroup canvasGroup;// Use this for initializationpublic virtual void Start () {slotList = GetComponentsInChildren<Slot>();canvasGroup = GetComponent<CanvasGroup>();}//动画void Update(){if (canvasGroup.alpha != targetAlpha){canvasGroup.alpha = Mathf.Lerp(canvasGroup.alpha, targetAlpha, smoothing * Time.deltaTime);if (Mathf.Abs(canvasGroup.alpha - targetAlpha) < .01f){canvasGroup.alpha = targetAlpha;}}}/// <summary>/// 根据ID存储物品/// </summary>/// <param name="id"></param>/// <returns></returns>public bool StoreItem(int id){Item item = InventoryManager.Instance.GetItemById(id);return StoreItem(item);}/// <summary>/// 根据物品存储物品/// </summary>/// <param name="item"></param>/// <returns></returns>public bool StoreItem(Item item){if (item == null){Debug.LogWarning("要存储的物品的id不存在");return false;}if (item.Capacity == 1){Slot slot = FindEmptySlot();if (slot == null){Debug.LogWarning("没有空的物品槽");return false;}else{slot.StoreItem(item);//把物品存储到这个空的物品槽里面}}else{Slot slot = FindSameIdSlot(item);if (slot != null){slot.StoreItem(item);}else{Slot emptySlot = FindEmptySlot();if (emptySlot != null){emptySlot.StoreItem(item);}else{Debug.LogWarning("没有空的物品槽");return false;}}}return true;}/// <summary>/// 这个方法用来找到一个空的物品槽/// </summary>/// <returns></returns>private Slot FindEmptySlot(){foreach (Slot slot in slotList){if (slot.transform.childCount == 0){return slot;}}return null;}/// <summary>/// 如果这个物品槽有物品,而且是同类型物品,/// 而且没有满,就返回这个物品槽/// </summary>/// <param name="item"></param>/// <returns></returns>private Slot FindSameIdSlot(Item item){foreach (Slot slot in slotList){if (slot.transform.childCount >= 1 && slot.GetItemId() == item.ID &&slot.IsFilled()==false ){return slot;}}return null;}/// <summary>/// 通过canvasGroup来控制面板显示,并且可以交互/// </summary>public void Show(){canvasGroup.blocksRaycasts = true;targetAlpha = 1;}/// <summary>/// 通过canvasGroup来控制面板隐藏,并且不可以交互/// </summary>public void Hide(){canvasGroup.blocksRaycasts = false;targetAlpha = 0;}/// <summary>/// 控制显示和隐藏的开关/// </summary>public void DisplaySwitch(){if (targetAlpha == 0){Show();}else{Hide();}}#region save and loadpublic void SaveInventory(){StringBuilder sb = new StringBuilder();foreach (Slot slot in slotList){if (slot.transform.childCount > 0){ItemUI itemUI = slot.transform.GetChild(0).GetComponent<ItemUI>();sb.Append(itemUI.Item.ID + ","+itemUI.Amount+"-");}else{sb.Append("0-");}}PlayerPrefs.SetString(this.gameObject.name, sb.ToString());}public void LoadInventory(){if (PlayerPrefs.HasKey(this.gameObject.name) == false) return;string str = PlayerPrefs.GetString(this.gameObject.name);//print(str);string[] itemArray = str.Split('-');for (int i = 0; i < itemArray.Length-1; i++){string itemStr = itemArray[i];if (itemStr != "0"){//print(itemStr);string[] temp = itemStr.Split(',');int id = int.Parse(temp[0]);Item item = InventoryManager.Instance.GetItemById(id);int amount = int.Parse(temp[1]);for (int j = 0; j < amount; j++){slotList[i].StoreItem(item);}}}}#endregion
}

背包类。

using UnityEngine;
using System.Collections;public class Knapsack : Inventory
{#region 单例模式private static Knapsack _instance;public static Knapsack Instance{get{if (_instance == null){_instance =  GameObject.Find("KnapsackPanel").GetComponent<Knapsack>();}return _instance;}}#endregion
}

箱子类。

using UnityEngine;
using System.Collections;public class Chest : Inventory {#region 单例模式private static Chest _instance;public static Chest Instance{get{if (_instance == null){_instance = GameObject.Find("ChestPanel").GetComponent<Chest>();}return _instance;}}#endregion
}

角色装备类。

using UnityEngine;
using System.Collections;
using UnityEngine.UI;public class CharacterPanel : Inventory
{#region 单例模式private static CharacterPanel _instance;public static CharacterPanel Instance{get{if (_instance == null){_instance = GameObject.Find("CharacterPanel").GetComponent<CharacterPanel>();}return _instance;}}#endregionprivate Text propertyText;private Player player;public override void Start(){base.Start();propertyText = transform.Find("PropertyPanel/Text").GetComponent<Text>();player = GameObject.FindGameObjectWithTag("Player").GetComponent<Player>();UpdatePropertyText();Hide();}/// <summary>/// 装备物品/// </summary>/// <param name="item"></param>public void PutOn(Item item){Item exitItem = null;foreach (Slot slot in slotList){EquipmentSlot equipmentSlot = (EquipmentSlot)slot;if (equipmentSlot.IsRightItem(item)){if (equipmentSlot.transform.childCount > 0){ItemUI currentItemUI= equipmentSlot.transform.GetChild(0).GetComponent<ItemUI>();exitItem = currentItemUI.Item;currentItemUI.SetItem(item, 1);}else{equipmentSlot.StoreItem(item);}break;}}if(exitItem!=null)Knapsack.Instance.StoreItem(exitItem);UpdatePropertyText();}/// <summary>/// 卸载物品/// </summary>/// <param name="item"></param>public void PutOff(Item item){Knapsack.Instance.StoreItem(item);UpdatePropertyText();}/// <summary>/// 更新属性/// </summary>private void UpdatePropertyText(){//Debug.Log("UpdatePropertyText");int strength = 0, intellect = 0, agility = 0, stamina = 0, damage = 0;foreach(EquipmentSlot slot in slotList){if (slot.transform.childCount > 0){Item item = slot.transform.GetChild(0).GetComponent<ItemUI>().Item;if (item is Equipment){Equipment e = (Equipment)item;strength += e.Strength;intellect += e.Intellect;agility += e.Agility;stamina += e.Stamina;}else if (item is Weapon){damage += ((Weapon)item).Damage;}}}strength += player.BasicStrength;intellect += player.BasicIntellect;agility += player.BasicAgility;stamina += player.BasicStamina;damage += player.BasicDamage;string text = string.Format("力量:{0}\n智力:{1}\n敏捷:{2}\n体力:{3}\n攻击力:{4} ", strength, intellect, agility, stamina, damage);propertyText.text = text;}}

商店类。

using UnityEngine;
using System.Collections;/// <summary>
/// 商店类
/// </summary>
public class Vendor : Inventory {#region 单例模式private static Vendor _instance;public static Vendor Instance{get{if (_instance == null){_instance = GameObject.Find("VendorPanel").GetComponent<Vendor>();}return _instance;}}#endregionpublic int[] itemIdArray;private Player player;public override void Start(){base.Start();InitShop();player = GameObject.FindGameObjectWithTag("Player").GetComponent<Player>();Hide();}private void InitShop(){foreach (int itemId in itemIdArray){StoreItem(itemId);}}/// <summary>/// 主角购买/// </summary>/// <param name="item"></param>public void BuyItem(Item item){bool isSuccess = player.ConsumeCoin(item.BuyPrice);if (isSuccess){Knapsack.Instance.StoreItem(item);}}/// <summary>/// 主角出售物品/// </summary>public void SellItem(){int sellAmount = 1;if (Input.GetKey(KeyCode.LeftControl)){sellAmount = 1;}else{sellAmount = InventoryManager.Instance.PickedItem.Amount;}int coinAmount = InventoryManager.Instance.PickedItem.Item.SellPrice * sellAmount;player.EarnCoin(coinAmount);InventoryManager.Instance.RemoveItem(sellAmount);}
}

锻造面板类。

using UnityEngine;
using System.Collections;
using System.Collections.Generic;/// <summary>
/// 锻造面板类
/// </summary>
public class Forge : Inventory {#region 单例模式private static Forge _instance;public static Forge Instance{get{if (_instance == null){_instance = GameObject.Find("ForgePanel").GetComponent<Forge>();}return _instance;}}#endregionprivate List<Formula> formulaList;public override void Start(){base.Start();ParseFormulaJson();}void ParseFormulaJson(){formulaList = new List<Formula>();TextAsset formulasText = Resources.Load<TextAsset>("Formulas");string formulasJson = formulasText.text;//配方信息的Json数据JSONObject jo = new JSONObject(formulasJson);foreach (JSONObject temp in jo.list){int item1ID = (int)temp["Item1ID"].n;int item1Amount = (int)temp["Item1Amount"].n;int item2ID = (int)temp["Item2ID"].n;int item2Amount = (int)temp["Item2Amount"].n;int resID = (int)temp["ResID"].n;Formula formula = new Formula(item1ID, item1Amount, item2ID, item2Amount, resID);formulaList.Add(formula);}//Debug.Log(formulaList[1].ResID);}public void ForgeItem(){// 得到当前有哪些材料// 判断满足哪一个秘籍的要求List<int> haveMaterialIDList = new List<int>();//存储当前拥有的材料的idforeach (Slot slot in slotList){if (slot.transform.childCount > 0){ItemUI currentItemUI = slot.transform.GetChild(0).GetComponent<ItemUI>();for (int i = 0; i < currentItemUI.Amount; i++){haveMaterialIDList.Add(currentItemUI.Item.ID);//这个格子里面有多少个物品 就存储多少个id}}}Formula matchedFormula = null;foreach (Formula formula in formulaList){bool isMatch = formula.Match(haveMaterialIDList);if (isMatch){matchedFormula = formula; break;}}if (matchedFormula != null){Knapsack.Instance.StoreItem(matchedFormula.ResID);//去掉消耗的材料foreach(int id in matchedFormula.NeedIdList){foreach (Slot slot in slotList){if (slot.transform.childCount > 0){ItemUI itemUI = slot.transform.GetChild(0).GetComponent<ItemUI>();if (itemUI.Item.ID == id&& itemUI.Amount > 0){itemUI.ReduceAmount(); if (itemUI.Amount <= 0){DestroyImmediate(itemUI.gameObject);}break;}}}}}}
}

玩家类。

using UnityEngine;
using System.Collections;
using UnityEngine.UI;public class Player : MonoBehaviour
{#region basic propertyprivate int basicStrength = 10;private int basicIntellect = 10;private int basicAgility = 10;private int basicStamina = 10;private int basicDamage = 10;public int BasicStrength{get{return basicStrength;}}public int BasicIntellect{get{return basicIntellect;}}public int BasicAgility{get{return basicAgility;}}public int BasicStamina{get{return basicStamina;}}public int BasicDamage{get{return basicDamage;}}#endregionprivate int coinAmount = 100;private Text coinText;public int CoinAmount{get{return coinAmount;}set{coinAmount = value;coinText.text = coinAmount.ToString();}}void Start(){coinText = GameObject.Find("Coin").GetComponentInChildren<Text>();coinText.text = coinAmount.ToString();}// Update is called once per framevoid Update () {//G 随机得到一个物品放到背包里面if (Input.GetKeyDown(KeyCode.G)){int id = Random.Range(1, 18);Knapsack.Instance.StoreItem(id);}//T 控制背包的显示和隐藏if (Input.GetKeyDown(KeyCode.T)){Knapsack.Instance.DisplaySwitch();}//Y 控制箱子的显示和隐藏if (Input.GetKeyDown(KeyCode.Y)){Chest.Instance.DisplaySwitch();}//U 控制角色面板的 显示和隐藏if (Input.GetKeyDown(KeyCode.U)){CharacterPanel.Instance.DisplaySwitch();}//I 控制商店显示和隐藏 if (Input.GetKeyDown(KeyCode.I)){Vendor.Instance.DisplaySwitch();}//O 控制锻造界面显示和隐藏 if (Input.GetKeyDown(KeyCode.O)){Forge.Instance.DisplaySwitch();}}/// <summary>/// 消费/// </summary>public bool ConsumeCoin(int amount){if (coinAmount >= amount){coinAmount -= amount;coinText.text = coinAmount.ToString();return true;}return false;}/// <summary>/// 赚取金币/// </summary>/// <param name="amount"></param>public void EarnCoin(int amount){this.coinAmount += amount;coinText.text = coinAmount.ToString();}
}

unity 背包系统之美相关推荐

  1. Unity背包系统-2:数据库存储方法ScriptableObject和显示背包物品InventoryManager

    1. 数据库脚本 1.1 元素(item)代码: using System.Collections; using System.Collections.Generic; using UnityEngi ...

  2. unity面试之美(四)

    1.面试方式:所有面试,只有3家有面试题,蓝港是其中之一,题量2-4页不等:其他都是1对1,2对1,或者3对1直接面试:主要考C#.unity基础,大公司问的不难,但问得深,基础必须扎实. 2.3D图 ...

  3. IGDATaiwan上Unity 优化讲座III

    IGDATaiwan上Unity 优化讲座III (罗志达) https://www.youtube.com/user/IGDATaiwan 议程: https://2019.tgdf.tw/agen ...

  4. Unity简单实现对话功能

    Unity背包系统 简单说明 TextAsse相关使用 协程的相关使用 相关素材 UI相关创建 创建TextAsset支持的格式对话文本 提示:以下是本篇文章正文内容 简单说明 主要使用TextAss ...

  5. Unity 物品模型旋转展示

    面板结构 相机结构 实现方法 使用RawImage显示RenderTexture,RenderTexture的图像来源为物品细节摄像机. 将物品生成在指定的位置上,然后用一个控制器让其自动旋转,再用聚 ...

  6. unity技美27——优化项目内美术3D,2D等资源,详解unity打包体的潜规则与案例

    很多朋友美术朋友在面试中经常会被问到一类问题,就是怎么优化你的美术资源. 当我们不熟练使用unity,以级不懂得unity的潜规则时,美术能做到的仅仅是: 1优化模型面数.或者用次世代的方式制作法线贴 ...

  7. Unity 游戏黑暗之光笔记第五章 背包系统的实现

    Unity 游戏黑暗之光笔记 第五章 背包系统的实现 详细过程参考,笔者一直有BUG--导致后面的很多内容没法写全 1.开发功能按钮 注意Anchors的位置,可以让图标在窗口变化时保持相对位置不会变 ...

  8. unity简单的背包系统笔记(有视频讲解)

    视频参考:Unity教程:背包系统:04:显示在背包里(C# code) InventoryManager_哔哩哔哩_bilibili 素材下载: https://pan.baidu.com/s/1o ...

  9. Unity 简易背包系统:工作台合成和配方

    Unity 简易背包系统系列 普通工作台的实现 〇. 实现原理 1. 行为脚本 2. 可编辑脚本 一. 具体实现步骤 1. 拖动单元(修改) 2. 数据型拖动单元 3. 数据型储存单元 4. 单元配方 ...

最新文章

  1. matlab实现周期阶跃函数,连续时间信号傅利叶变换与MATLAB实现.doc
  2. 每日一皮:当代互联网企业真实写照!
  3. python【数据结构与算法】搜索初探
  4. 进阶学习(1) Gradle 项目管理工具的使用
  5. spring中lazy-init详解
  6. decode的mysql用法_MySQL DECODE( )用法及代码示例
  7. js 获取某iframe中document,浏览器兼容
  8. 可视化工具Navicat for MySQL-操作三
  9. Windows下搭建ESP-IDF开发环境,适合ESP32/S2/C3/S3系列模组二次开发
  10. Joe一款个人博客typecho主题(扩展版)
  11. 3.15 Ext JS 之 Tooltip 的基本使用
  12. html5游戏开发-零基础开发RPG游戏-开源讲座(四)
  13. pfa100_什么是PFA?
  14. 怎么用Python写出随时间变化的字_面试必备 | 带你彻底搞懂 Python 生成器
  15. php中中文字符串的截取和获取长度 mb_substr() mb_strlen()
  16. [AI教程]最全人工智能图谱解析和视频下载
  17. 软件测试主要流程分享
  18. idea破解(到2100年)
  19. Android音乐播放器
  20. 大联大品佳集团推出基于Audiowise产品的蓝牙5.1助听(Hearing Device)耳机方案

热门文章

  1. 救援人员抵达受灾海啸袭击的岩手县Otsuchi镇(高清组图)
  2. 辅助DNS SERVICE 配置工作任务-winserver2
  3. 小米2 android版本更新,小米2手机怎么升级MIUI系统?小米2在线升级的教程
  4. python 一行代码 微信_一行代码!生成自己QQ、微信的动态二维码
  5. Mule学习(五、Mule Expression Language - MEL表达式)
  6. 安卓手机刷机liunx服务器_有没有办法把闲置的手机(Android)刷个linux系统?
  7. android 随机播放代码,Android | 一个随机播放网络音乐的小 Demo
  8. Python(我的世界)-第一讲
  9. 作用域和作用域链及预解析
  10. 分享视频直播常见问题与解决办法汇总