设计物品的UML类图

开发Item物品类

using System.Collections;
using System.Collections.Generic;
using UnityEngine;//物品基类
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 Item(int id,string name,ItemType type,ItemQuality quality,string des,int capacity,int buyPrice,int sellPirce){this.ID = id;this.Type = type;this.Quality = quality;this.Description = des;this.Capacity = capacity;this.BuyPrice = buyPrice;this.SellPrice = sellPirce;}//物品类型public enum ItemType{Consumable,Equipment,Weapon,Material}//品质public enum ItemQuality{Common,UnCommon,Rare,Epic,Legendary,Artifact}
}

开发消耗品类、装备类、武器类和材料类

在Item类添加一个新的构造方法

    public Item(){this.ID = -1;}

消耗品类

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
/// <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 sellPirce,int hp,int mp): base(id, name, type, quality, des, capacity, buyPrice, sellPirce){this.HP = hp;this.MP = mp;}
}

装备类

using System.Collections;
using System.Collections.Generic;
using UnityEngine;/// <summary>
/// 装备类
/// </summary>
public class Equipment : Item
{public int Strength { get; set; }//力量public int Intellect { get; set; }//智力  public int Agility { get; set; }//敏捷public int Stamina { get; set; }//体力public EquipmentType EquipType { get; set; }public Equipment(int id, string name, ItemType type, ItemQuality quality, string des, int capacity, int buyPrice, int sellPirce,int strength,int intellect,int agility,int stamina,EquipmentType equipType):base(id, name, type, quality, des, capacity, buyPrice, sellPirce){this.Strength = strength;this.Intellect = intellect;this.Agility = agility;this.Stamina = stamina;this.EquipType = equipType;}public enum EquipmentType{Head,Neck,Ring,Leg,Bracer,Boots,Trinket,Shoulder,Belt,OffHand,}}

武器类

using System.Collections;
using System.Collections.Generic;
using UnityEngine;/// <summary>
/// 武器类
/// </summary>
public class Weapon : Item
{public int Damage { get; set; }public WeaponType WpType;public Weapon(int id, string name, ItemType type, ItemQuality quality, string des, int capacity, int buyPrice, int sellPirce,int damage,WeaponType wpType):base(id, name, type, quality, des, capacity, buyPrice, sellPirce){this.Damage = damage;this.WpType = wpType;}public enum WeaponType{OffHand,MainHand}
}

材料类

using System.Collections;
using System.Collections.Generic;
using UnityEngine;/// <summary>
/// 材料类
/// </summary>
public class Material : Item
{}

设计物品类的Json文件

通过下面的网址在线设计Json文件

http://www.bejson.com/jsoneditoronline/

设计一个药品类的Json文件

[{"id": 1,"name": "血瓶","type": "Consumable","quality": "Common","description": "这个是用来加血的","capacity": 10,"buyPrice": 10,"sellPrice": 5,"hp": 10,"mp": 0,"sprite": "Sprites/Items/hp"}
]

开发InventoryManager物品管理器

using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class InventoryManager : MonoBehaviour
{//单例模式private static InventoryManager _instance;public static InventoryManager Instance{get{if(_instance == null){//下面的代码只会执行一次_instance = GameObject.Find("InventoryManager").GetComponent<InventoryManager>();}return _instance;}}
}

Json解析过程

使用JSONObject来进行解析

    /// <summary>/// 解析物品信息/// </summary>void ParseItemJson(){itemList = new List<Item>();//文本在Untiy里面是 TextAsset类型TextAsset itemText = Resources.Load("Items") as TextAsset;string itemsJson = itemText.text;JSONObject j = new JSONObject(itemsJson);foreach (JSONObject temp in j.list){Item.ItemType type = (Item.ItemType)System.Enum.Parse(typeof(Item.ItemType), temp["type"].str);//下面解析这个对象里面的公有属性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://TODObreak;case Item.ItemType.Weapon://TODObreak;case Item.ItemType.Material://TODObreak;}itemList.Add(item);Debug.Log(item);}}

设计背包的UI

开发Slot和Item的Prefab预制体

更改Knapsack和Chest的设计

定义一个Inventory类

using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class Inventory : MonoBehaviour
{private Slot[] slotList;virtual public void Start(){slotList = GetComponentsInChildren<Slot>();}}

给Inventory添加物品存储的功能

首先在InventoryManager中添加一个通过id寻找物品的办法

    public Item GetItemById(int id){foreach (Item item in itemList){if(item.ID == id){return item;}}return null;}

在Inventory里面添加物品存储的代码,首先考虑需要新的空格子存储的情况

   public bool StoreItem(int id){Item item = InventoryManager.Instance.GetItemById(id);return StoreItem(item);}public bool StoreItem(Item item){if(item == null){Debug.Log("要存储的物品id不存在");return false;}if(item.Capacity == 1){//TODOSlot slot = FindEmptySlot();if (slot == null){Debug.Log("没有新的物品槽可以添加物品。");}else{slot.StoreItem(item);//把物品存储到这个空的物品槽里面}}else{}}/// <summary>/// 这个方法用来寻找新的物品槽/// </summary>/// <returns></returns>private Slot FindEmptySlot(){foreach (Slot slot in slotList){if(slot.transform.childCount == 0){return slot;}}return null;}
}

完善物品存储功能

给ItemUI中定义两个属性

using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class ItemUI : MonoBehaviour
{public Item Item { get; set; }public int Amount { get; set; }
}

然后在Slot里面 添加三个方法 ,分别是存储item,得到当前存储item的类型以及是否超过容量。

    /// <summary>/// 把item放在自身下面/// 如果自身下面已经有item了,amount++/// 如果没有,根据itemPrefab去实例化一个item,放在下面/// </summary>/// <param name="item"></param>public void StoreItem(Item item){}/// <summary>/// 得到当前物品槽存储的物品类型/// </summary>public Item.ItemType GetItemType(){return transform.GetChild(0).GetComponent<ItemUI>().Item.Type;}/// <summary>/// Is Slot Filled?/// </summary>/// <returns></returns>public bool IsFilled(){ItemUI itemUI = transform.GetChild(0).GetComponent<ItemUI>();return itemUI.Amount >= itemUI.Item.Capacity;//当前的数量大于等于容量}

在Inventory中完善物品存储功能

    public bool StoreItem(Item item){if(item == null){Debug.Log("要存储的物品id不存在");return false;}if(item.Capacity == 1){//TODOSlot slot = FindEmptySlot();if (slot == null){Debug.Log("没有新的物品槽可以添加物品。");return false;}else{slot.StoreItem(item);//把物品存储到这个空的物品槽里面}}else{Slot slot = FindSameTypeSlot(item);if(EmptySlot != null){slot.StoreItem(item);}else{Slot EmptySlot = FindEmptySlot();if(slot != null){EmptySlot.StoreItem(item);}else{Debug.Log("没有新的物品槽可以添加物品。");return false;}}}return true;}private Slot FindSameTypeSlot(Item item){foreach (Slot slot in slotList){if(slot.transform.childCount>=1 && slot.GetItemType() == item.Type && slot.IsFilled() == false){return slot;}}return null;}

开发Slot的StoreItem存储功能

首先在ItemUI里面添加两个方法,一个用来设置Item里面的属性,一个用来更新数量

    public void SetItem(Item item,int amount = 1){this.Item = item;this.Amount = amount;//UpdateUI}public void AddAmount(int amout = 1){this.Amount += amout;//UpdateUI}

完善Slot的StoreItem存储功能

    /// <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.localPosition = Vector3.zero;itemGameObject.GetComponent<ItemUI>().SetItem(item);}else{transform.GetChild(0).GetComponent<ItemUI>().AddAmount();}}

测试背包物品存储功能

新建一个Player物体用来进行测试

using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class Player : MonoBehaviour
{// Update is called once per framevoid Update(){//F 随机得到一个物品放到背包里面if (Input.GetKeyDown(KeyCode.F)){int id = Random.Range(1, 2);Knapsack.Instance.StoreItem(id);}}
}

背包中物品的UI更新显示

在ItemUI中添加两个属性

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

在ItemUI里添加更新图片和数字的方法

    public void SetItem(Item item, int amount = 1){this.Item = item;this.Amount = amount;ItemImage.sprite = Resources.Load<Sprite>(item.Sprite);AmountText.text = Amount.ToString();}public void AddAmount(int amout = 1){this.Amount += amout;AmountText.text = Amount.ToString();}

设计ToolTip的UI

添加一个Content Size Fitter组件,让其自适应

开发ToolTip类控制提示信息显示和隐藏

新建一个ToolTip脚本,添加控制提示信息显示和隐藏的办法,通过CanvasGroup里的Alpha来实现

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;public class ToolTip : MonoBehaviour
{private Text toolTipText;private Text contentText;private CanvasGroup canvasGroup;private float targetAlpha = 0;public float smoothing = 1;private void Start(){toolTipText = GetComponent<Text>();contentText = transform.Find("Content").GetComponent<Text>();canvasGroup = GetComponent<CanvasGroup>();}private void Update(){if(canvasGroup.alpha != targetAlpha){Mathf.Lerp(canvasGroup.alpha, targetAlpha, smoothing * Time.deltaTime);if(Mathf.Abs( canvasGroup.alpha - targetAlpha) < 0.01f){canvasGroup.alpha = targetAlpha;}}}public void Show(string text){toolTipText.text = text;contentText.text = text;targetAlpha = 1;}public void Hide(){targetAlpha = 0;}
}

把ToolTip交给InventoryManager进行管理

    private ToolTip toolTip;private void Start(){ParseItemJson();toolTip = GameObject.FindObjectOfType<ToolTip>();}public void ShowToolTip(string content){toolTip.Show(content);}public void HideToolTip(){toolTip.Hide();}

检测鼠标的进入和移除 控制ToolTip的显示和隐藏

在Item里面添加一个显示信息的代码

    /// <summary>/// 得到提示面板应该显示什么样的内容/// </summary>/// <returns></returns>public virtual string GetToolTipText(){return Name +": " + Description;//TODO}

在Slot里面添加两个接口,用来处理鼠标的交互

IPointerEnterHandler,IPointerExitHandler

    public void OnPointerEnter(PointerEventData eventData){if (transform.childCount > 0){string toolTipText = transform.GetChild(0).GetComponent<ItemUI>().Item.GetToolTipText();InventoryManager.Instance.ShowToolTip(toolTipText);}     }public void OnPointerExit(PointerEventData eventData){if (transform.childCount > 0)InventoryManager.Instance.HideToolTip();}

控制提示信息面板的跟随

添加一个isToolTipShow变量,用来给ToolTip当标志

    private bool isToolTipShow = false;
    public void ShowToolTip(string content){isToolTipShow = true;toolTip.Show(content);}public void HideToolTip(){isToolTipShow = false;toolTip.Hide();}

在Update里边添加跟随的代码

    private Canvas canvas;//偏移,为了让ToolTip更好的显示public Vector2 toolTipPositionOffset = new Vector2(150, -25);private void Update(){if (isToolTipShow){//控制提示面板跟随鼠标Vector2 position;//获取鼠标的位置RectTransformUtility.ScreenPointToLocalPointInRectangle(canvas.transform as RectTransform, Input.mousePosition, null, out position);toolTip.SetLocalPositon(position+toolTipPositionOffset);}}

在ToolTip中添加新方法,用来设置它的位置

    public void SetLocalPositon(Vector3 position){transform.localPosition = position;}

添加蓝瓶的Json和Fixbug

添加胸甲的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"}
]

控制装备类型Json信息的解析

                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;

为了让装备数目显示好看,修改ItemUI中的设置方法

        if (Item.Capacity > 1)AmountText.text = Amount.ToString();elseAmountText.text = "";

完善所有的装备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"}
]

武器Json信息的完善和解析

  {"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"}

完善解析

                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;

材料Json信息的完善和解析

  {"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"}

完善解析

                case Item.ItemType.Material:item = new Material(id, name, type, quality, description, capacity, buyPrice, sellPrice, sprite);break;

完善物品的提示信息显示

在Item里面完善物品提示信息显示,让显示变得好看,可以根据装备品质显示不同颜色

    /// <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;default: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;}
}

完善消耗品、装备和武器的提示信息显示

在消耗品类里添加以下代码

    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 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;default: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;}

在武器类里添加以下代码

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

在InventoryManager添加PickedI

创建一个Item叫做PickedItem用来做鼠标拖拽

    private ItemUI pickedItem;//鼠标选中的物体

首先在Start里面对其进行初始化

        pickedItem = GameObject.Find("PickedItem").GetComponent<ItemUI>();pickedItem.Hide();

在ItemUI里面添加要用到的方法

    public void Show(){gameObject.SetActive(true);}public void Hide(){gameObject.SetActive(false);}public void SetLocalPostion(Vector3 posiiton){transform.localPosition = posiiton;}

物品移动各种情况分析

使用IPointerDownHandler进行鼠标拖拽,首先分析以下物品移动的各种情况

    public void OnPointerDown(PointerEventData eventData){//自身是空 1.pickedItem != null pickedItem放在这个位置//按下ctrl        放置当前鼠标上的物体的一个//没有按下ctrl      放置当前鼠标上的物品的所有//         2.pickedItem == null 不做任何处理//自身不是空 1.pickedItem != null pickedItem跟当前物品进行交换//自身的id==pickedItem.id//按下ctrl        放置当前鼠标上物品的一个//没有按下ctrl      放置当前鼠标上的物品的所有//可以完全放下//只能放下其中一部分//自身的id!=pickedItem.id      pickedItem跟当前物品交换//           2.pickedItem == null 把当前物品槽里面的物品放到鼠标上//按下ctrl        取得当前物品槽中物品的一半//没有按下ctrl      取得当前物品槽中物品的所有}

处理物品的捡起

    public void OnPointerDown(PointerEventData eventData){//自身是空 1.isPickedItem == true pickedItem放在这个位置//按下ctrl        放置当前鼠标上的物体的一个//没有按下ctrl      放置当前鼠标上的物品的所有//         2.isPickedItem == false  不做任何处理//自身不是空 1.isPickedItem == true pickedItem跟当前物品进行交换//自身的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)){//TODO}else{                   //把当前物品槽的信息 复制给PickedItem(跟随鼠标移动)InventoryManager.Instance.PickedItem.SetItemUI(currentItem);InventoryManager.Instance.IsPickedItem = true;Destroy(currentItem.gameObject);}}}}        

处理物品数量的一半的捡起

在Slot中添加以下代码

            if(InventoryManager.Instance.IsPickedItem == false){if (Input.GetKey(KeyCode.LeftControl)){int amountPicked = (currentItem.Amount + 1) / 2;//捡起的数量InventoryManager.Instance.PickupItem(currentItem, amountPicked);int amountRemained = currentItem.Amount - amountPicked;if (amountRemained <= 0){Destroy(currentItem.gameObject);}else{currentItem.SetAmount(amountRemained);}}

需要在ItemUI中添加修改数量的方法

    public void SetAmount(int amount){this.Amount = amount;if (Item.Capacity > 1)AmountText.text = Amount.ToString();elseAmountText.text = "";}

在Inventory中添加捡起道具的方法

    //捡起物品槽中所有数量的物品public void PickupItem(ItemUI itemUI){PickedItem.SetItem(itemUI.Item, itemUI.Amount);IsPickedItem = true;}//捡起物品槽指定数目的物品public void PickupItem(ItemUI itemUI,int amount){PickedItem.SetItem(itemUI.Item,amount);IsPickedItem = true;}

控制选中物品跟随鼠标

在InventoryManager中添加控制选择物品跟随鼠标的代码

        if (isPickedItem){//如果我们捡起了物品,我们就要让物品跟随鼠标//控制提示面板跟随鼠标Vector2 position;//获取鼠标的位置RectTransformUtility.ScreenPointToLocalPointInRectangle(canvas.transform as RectTransform, Input.mousePosition, null, out position);pickedItem.SetLocalPostion(position);}

同时还需要隐藏ToolTip,我们修改下面两个方法

    //捡起物品槽中指定数量的物品public void PickupItem(Item item,int amount){PickedItem.SetItem(item,amount);PickedItem.Show();IsPickedItem = true;this.toolTip.Hide();}public void ShowToolTip(string content){if (this.isPickedItem) return;isToolTipShow = true;toolTip.Show(content);}

给物品添加显示的动画

在ItemUI中实现动画

    private float targetScale = 1f;private Vector3 animationScale = new Vector3(1.4f,1.4f,1.4f);private float smoothing = 4;private 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); }}}

然后在SetItem、AddAmount和SetAmount的方法中添加一条语句,用来初始化动画

        transform.localScale = animationScale;

按下Ctrl一个一个放置物品

在之前的方法中添加以下代码

            else{//自身是空 1.isPickedItem == true pickedItem放在这个位置//按下ctrl        放置当前鼠标上的物体的一个//没有按下ctrl      放置当前鼠标上的物品的所有//         2.isPickedItem == false  不做任何处理if(currentItem.Item.ID == InventoryManager.Instance.PickedItem.Item.ID){if (Input.GetKey(KeyCode.LeftControl)){if(currentItem.Item.Capacity > currentItem.Amount)//当前物品槽还有容量{currentItem.AddAmount();InventoryManager.Instance.RemoveOneItem();}else{return;}}}

在InventoryManager中添加拿掉一个物品放在物品槽里面的方法

    /// <summary>/// 从手上拿掉一个物品放在物品槽里面/// </summary>public void RemoveOneItem(){PickedItem.ReduceAmount();if (PickedItem.Amount <= 0){isPickedItem = false;PickedItem.Hide();}}

在ItemUI中添加减少数量的方法ReduceAmount

    public void ReduceAmount(int amout = 1){transform.localScale = animationScale;this.Amount -= amout;if (Item.Capacity > 1)AmountText.text = Amount.ToString();elseAmountText.text = "";}

最后不要忘记取消pickedItem上Raycast Target的勾选

物品放置-累加和剩余情况处理

继续完善之前的代码

                        //没有按下ctrl      放置当前鼠标上的物品的所有//可以完全放下//只能放下一部分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.RemoveAllItem();}else{//只能放下一部分currentItem.SetAmount(currentItem.Amount + amountRemain);InventoryManager.Instance.ReMoveItem(amountRemain);}}else{return;}}

在InventoryManager中添加需要的方法

    public void RemoveAllItem(){isPickedItem = false;PickedItem.Hide();}public void ReMoveItem(int amount){PickedItem.ReduceAmount(amount);}

处理把物品放到空的物品槽里面

        else{//自身是空 1.isPickedItem == true pickedItem放在这个位置//按下ctrl        放置当前鼠标上的物体的一个//没有按下ctrl      放置当前鼠标上的物品的所有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;}}

添加Chest箱子

创建一个箱子,在其上面添加Chest脚本进行管理,让Chest脚本继承Inventory。

处理物品的丢弃

在InventoryManager的Update中添加物品丢弃的方法

        //物品丢弃的处理if(isPickedItem && Input.GetMouseButtonDown(0) && UnityEngine.EventSystems.EventSystem.current.IsPointerOverGameObject(-1) == false){isPickedItem = false;pickedItem.Hide();}

控制背包的显示和隐藏

在Inventory中添加下面的代码

    private float targetAlpha = 1;//目标的透明度private float smoothing = 4;private CanvasGroup canvasGroup;virtual public void Start(){slotList = GetComponentsInChildren<Slot>();canvasGroup = GetComponent<CanvasGroup>();}private 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;}}}public void Show(){targetAlpha = 1;}public void Hide(){targetAlpha = 0;}public void DisplaySwitch(){if(targetAlpha == 0){Show();}else{Hide();}}

然后在Player里面进行调用

        //B 控制背包的显示的隐藏if (Input.GetKeyDown(KeyCode.B)){Knapsack.Instance.DisplaySwitch();}//Y 控制箱子的显示的隐藏if (Input.GetKeyDown(KeyCode.Y)){Chest.Instance.DisplaySwitch();}

处理物品交换

                    //自身的id!=pickedItem.id      pickedItem跟当前物品交换Item item = currentItem.Item;int amount = currentItem.Amount;currentItem.SetItem(InventoryManager.Instance.PickedItem.Item, InventoryManager.Instance.PickedItem.Amount);InventoryManager.Instance.PickedItem.SetItem(item, amount);

设计角色面板

管理角色面板所有的物品槽

创建一个新的EquipmentSlot类专门管理装备格子

using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class EquipmentSlot : Slot
{public Equipment.EquipmentType equipType;public Weapon.WeaponType wpType;}

给角色面板创建一个CharacterPanel进行管理

using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class CharacterPanel : Inventory
{private EquipmentSlot mainHandSLot;private EquipmentSlot offHandSlot;public override void Start(){base.Start();mainHandSLot = transform.Find("MainHandSlot").GetComponent<EquipmentSlot>();offHandSlot = transform.Find("OffHandSlot").GetComponent<EquipmentSlot>();}
}

分析装备拖拽穿戴方式的情况

在EquipmentSlot里重写点击装备槽的方法,首先考虑出现的情况

    public override void OnPointerDown(PointerEventData eventData){//手上有 东西//当前装备槽有装备//无装备//手上没东西//当前装备槽有装备//无装备   不做处理}

处理装备的穿戴

在EquipmentSlot中重写点击装备槽的方法

public override void OnPointerDown(PointerEventData eventData){//手上有 东西//当前装备槽有装备//无装备//手上没东西//当前装备槽有装备//无装备   不做处理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)){//Item item = currentItemUI.Item;//int amount = currentItemUI.Amount;//currentItemUI.SetItem(pickedItem.Item, pickedItem.Amount);//InventoryManager.Instance.PickedItem.SetItem(item, amount);currentItemUI.Exchange(InventoryManager.Instance.PickedItem);}}else//手上有装备 物品槽没装备{if (IsRightItem(pickedItem.Item)){this.StoreItem(InventoryManager.Instance.PickedItem.Item);InventoryManager.Instance.RemoveItem(1);}}}else{}}/// <summary>/// 判断item是否合适放在这个位置/// </summary>private 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;}

装备的穿戴和卸下

完善之前的代码

        else//手上没东西{if (transform.childCount > 0)//物品槽有装备{ItemUI currentItemUI = transform.GetChild(0).GetComponent<ItemUI>();InventoryManager.Instance.PickupItem(currentItemUI.Item, currentItemUI.Amount);Destroy(currentItemUI.gameObject);}}

处理装备的右击事件

首先给之前Slot和EquipmentSlot里的方法添加左键点击权限

        //使用左键点击才能生效if (eventData.button != PointerEventData.InputButton.Left) return;

在Slot里面添加装备的右键点击事件

        //使用右键点击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();Item currentItem = currentItemUI.Item;if (currentItemUI.Amount <= 0){DestroyImmediate(currentItemUI.gameObject);InventoryManager.Instance.HideToolTip();}CharacterPanel.Instance.PutOn(currentItem);}}}

处理装备的自动穿戴

在CharacterPanel里面添加自动穿戴的方法PutOn

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

处理装备的脱下

首先在EquipmentSlot的事件点击添加右键点击的方法

        //使用右键点击if (eventData.button == PointerEventData.InputButton.Right){if (InventoryManager.Instance.IsPickedItem == false && transform.childCount > 0){ItemUI currentItemUI = transform.GetChild(0).GetComponent<ItemUI>();//脱掉装备放到背包里面去transform.parent.SendMessage("PutOff", currentItemUI.Item);Destroy(currentItemUI.gameObject);InventoryManager.Instance.HideToolTip();}}

在CharacterPanel里面添加脱掉装备的方法PutOff

    public void PutOff(Item item){Knapsack.Instance.StoreItem(item);}

控制角色面板的显示和隐藏

Player脚本里面 添加下面代码

        //U 控制角色面板的显示和隐藏if (Input.GetKeyDown(KeyCode.U)){CharacterPanel.Instance.DisplaySwitch();}

控制角色面板的属性显示

在Character中添加更新属性栏的方法

    private void 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){Weapon w = (Weapon)item;damage += w.Damage;}}}strength += player.BasicStrength;intellect += player.BasicIntellect;agility += player.BasicAgility;stamina += player.BasicStamina;damage += player.BasicDamage;string text = string.Format("力量:{0}\n智力:{0}\n敏捷:{0}\n体力:{0}\n攻击力:{4}", strength, intellect, agility, stamina, damage);propertyText.text = text;}

然后在脱掉装备和穿上装备的地方进行更新。

设计小贩商店

小贩商店中物品的初始化

创建Vendor和VendorSlot脚本

在Vendor里面进行贩卖物品的初始化

using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class Vendor : Inventory
{public int[] itemIdArray;public override void Start(){base.Start();InitShop();}private void InitShop(){foreach(int itemId in itemIdArray){StoreItem(itemId);}}
}

给角色添加金币属性

在Player里面添加金币属性,然后添加消费金币和赚取金币的方法

    private int coinAmount = 100;private Text coinText;private void Start(){coinText = GameObject.Find("Coin").GetComponentInChildren<Text>();coinText.text = coinAmount.ToString();}/// <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 EarnCoint(int amount){this.coinAmount += amount;coinText.text = coinAmount.ToString();}

物品购买功能

在VendorSlot中添加物品的购买功能

    public override void OnPointerDown(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);}}}

Vendor中的购买物品方法BuyItem为

    public void BuyItem(Item item){bool isSuccess = player.ConsumeCoin(item.BuyPrice);if (isSuccess){Knapsack.Instance.StoreItem(item);}}

物品出售功能

在VendorSlot中出售物品的购能

        else if(eventData.button == PointerEventData.InputButton.Left && InventoryManager.Instance.IsPickedItem == true){transform.parent.parent.SendMessage("SellItem");}

Vendor中的出售物品方法SellItem为

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

设计锻造系统界面

设计锻造系统的秘方类和秘方Json

创建秘方类Formula

using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class Formula
{public int Item1ID { get; set; }public int Item1Amount { get; set; }public int Item2ID { get; set; }public int Item2Amount { get; set; }public int ResID { get; set; }//锻造结果的物品}

创建秘方Json

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

解析秘方Json

在Forge中完成对秘方Json的解析

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

开发物品合成的核心匹配算法

在Forge里面添加锻造按钮的事件ForgeItem

    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里添加锻造物品id匹配的方法

    private List<int> needIdList = new List<int>();//所需要物品的idpublic 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>public bool Match(List<int> idList)//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;}

物品的合成锻造生成处理

完善ForgeItem方法

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

控制锻造界面和商店界面的显示和隐藏

        //I 控制商店的显示和隐藏if (Input.GetKeyDown(KeyCode.I)){Vendor.Instance.DisplaySwitch();}//O 控制锻造的显示和隐藏if (Input.GetKeyDown(KeyCode.O)){Forge.Instance.DisplaySwitch();}

控制物品的存储和加载

在Inventory里面添加控制物品存储和加载的方法

    public 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);string[] itemArray = str.Split('-');for(int i = 0; i < itemArray.Length - 1; i++){string itemStr = itemArray[i];if(itemStr != "0"){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);}}}}

在InventoryManager中进行调用

    public void SaveInventory(){Knapsack.Instance.SaveInventory();Chest.Instance.SaveInventory();CharacterPanel.Instance.SaveInventory();Forge.Instance.SaveInventory();PlayerPrefs.SetInt("CoinAmount", GameObject.FindGameObjectWithTag("Player").GetComponent<Player>().CoinAmount);}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");}}

点击保存后终止游戏,重新运行游戏点击加载

背包系统 装备系统和锻造系统 - 基于Unity2018 UGUI相关推荐

  1. 基于Unity3D(UGUI)的背包系统(装备系统,锻造系统,购买系统)

    好了,开始进入正题! 先给出部分效果图: 背包是用来存放角色在游戏中获得的物品,箱子是用来临时保存物品的(只有保存功能),角色面板是用来模拟给角色装备物品的,武器,服饰等,最右边红色字体的面板是用来显 ...

  2. 蜀门锻造系统c语言原理,蜀门手游装备怎么锻造 装备锻造详解

    蜀门手游里装备锻造后可以有很大的提升,装备自然就会变得更加厉害了,赶紧来看看蜀门手游装备怎么锻造 装备锻造详解. 在锻造系统中,坐骑.法宝和防具均可进行锻造,当法宝锻造等级达到+10,并且任意三件防具 ...

  3. 基于suse linux系统的cacti系统部署——rpm包方式

    豆丁 http://www.docin.com/p-191889788.html rpm包方式:啊扬--沙迳:2010-12-1:更改:2011/5/16:一.Cacti的简介(来源:网络):Cact ...

  4. web系统四层结构中服务器端,基于.NET平台构建四层B/S结构的动态网站

    摘要: Web是基于Internet技术的一种应用层服务,具有后台数据库支持的n层B/S结构已经成为动态Web应用的主流.虽然动态网站开发工作的主要是进行服务器端应用程序的开发,但是B/S结构动态We ...

  5. 基于Java毕业设计校园外卖零食商城系统源码+系统+mysql+lw文档+部署软件

    基于Java毕业设计校园外卖零食商城系统源码+系统+mysql+lw文档+部署软件 基于Java毕业设计校园外卖零食商城系统源码+系统+mysql+lw文档+部署软件 本源码技术栈: 项目架构:B/S ...

  6. java 抽奖系统源码_基于jsp的抽奖系统-JavaEE实现抽奖系统 - java项目源码

    基于jsp+servlet+pojo+mysql实现一个javaee/javaweb的抽奖系统, 该项目可用各类java课程设计大作业中, 抽奖系统的系统架构分为前后台两部分, 最终实现在线上进行抽奖 ...

  7. 基于Java毕业设计房屋租赁系统源码+系统+mysql+lw文档+部署软件

    基于Java毕业设计房屋租赁系统源码+系统+mysql+lw文档+部署软件 基于Java毕业设计房屋租赁系统源码+系统+mysql+lw文档+部署软件 本源码技术栈: 项目架构:B/S架构 开发语言: ...

  8. 计算机毕业设计Java基于的药品销售系统(源码+系统+mysql数据库+lW文档)

    计算机毕业设计Java基于的药品销售系统(源码+系统+mysql数据库+lW文档) 计算机毕业设计Java基于的药品销售系统(源码+系统+mysql数据库+lW文档) 本源码技术栈: 项目架构:B/S ...

  9. 基于Java毕业设计大学生校园兼职系统源码+系统+mysql+lw文档+部署软件

    基于Java毕业设计大学生校园兼职系统源码+系统+mysql+lw文档+部署软件 基于Java毕业设计大学生校园兼职系统源码+系统+mysql+lw文档+部署软件 本源码技术栈: 项目架构:B/S架构 ...

最新文章

  1. 秋招必备:斩获腾讯offer的简历分享!
  2. kubernetes log 流式数据处理
  3. Linux查看当前http连接,51CTO博客-专业IT技术博客创作平台-技术成就梦想
  4. 【ARM】arm异常中断处理知识点
  5. 怎么做mysql查询系统_mysql数据库系统学习(一)---一条SQL查询语句是如何执行的?...
  6. html css导航栏字体图标,HTML+CSS入门之两种图标字体库
  7. linux+系统优化基础,Linux入门基础(三):Linux用户及权限基础
  8. 五分钟,手撸一个Spring容器!
  9. mysql alert longtext_mysql数据类型介绍(含text,longtext,mediumtext说明)
  10. 项目分层思路——管家婆
  11. 局域网内数据采集总结(三)
  12. 下一代的搜索引擎是什么样子?神经网络真的能「死记硬背」吗?
  13. 循环双链表的手动构建总结
  14. postgresql和greenplum使用笔记
  15. 程序员干货学习资源(持续更新)
  16. Shapley Values
  17. 游戏测试基础:适配性测试
  18. 2021全国特种设备-R1快开门式压力容器充装模拟考试题库一[安考星]
  19. 学习Mybatis框架(一)
  20. 图的单源最短路径算法

热门文章

  1. svg 动画 ------- svg的内容如何围绕自身旋转
  2. python获取目标时间距离现在多长时间(‘2020-5-30 23:40:00‘)
  3. 浅谈经济的真相,你无法逃避的问题(简论房地产是谁的噩梦)
  4. 浅谈溯源反制与防溯源
  5. 简易支付验证:即时支付、签名的有效性和交易的完整性
  6. 网易2018校园招聘:合唱 [python]
  7. JS一元运算符(前++,后++)详解
  8. [转]读懂美国大使馆发布的空气质量指数
  9. ServU配置网络盘
  10. mysql cc攻击_CC攻击数据详细分析