RPG游戏《黑暗之光》流程介绍与代码分析之(五):背包系统的实现(上)

第五章:背包系统

背包系统作为游戏中的一个重要功能,与游戏存在着诸多的交互性,购买商品、怪物掉落等各种情形都需要访问背包系统,结构较为复杂。因此背包系统将通过两篇博客进行分析。

(上)部分包括
  • 功能面板创建
  • 物品信息管理系统
  • 物品栏的UI界面

(下)部分偏向于功能实现,包括
  • 拾取操作的模拟
  • 背包的显示与隐藏
  • 物品提示信息窗口的实现

5.1功能面板

在之前的学习中,还没有功能面板进行创建,因此先创建整体的功能面板。为了实现各种系统,我们需要在UIRoot中创建一个Invisible Wigdet,也就是一个Container,设置其属性如下

添加所有的功能按钮,注意对其方式的左右要向右对齐,这样才能保证分辨率发生变化时图标也能随之自适应变化。

设置完成后如下

为了实现这5个功能按钮的事件监听,我们在Script下建立一个UI文件夹统一处理,新建FunctionBar脚本,存储5个按键功能,在之后的学习中进行完善。将这5个功能函数赋给5个按钮的On Click事件。
    public void OnStatusButtonClick()
    {
    }
    public void OnBagButtonClick()
    {
    }
    public void OnEquipButtonClik()
    {
    }
    public void OnSkillButtonClick()
    {
    }
    public void OnSettingButtonClick()
    {
    }
在之后的操作中我们会对这些按键功能进行完善。

5.2物品信息管理与外界访问

我们需要通过一个txt文档来储存所有的物品信息,在Assets下(Show in explorer)建立一个文本文档ObjectsInfoInList存储这些信息,如下图所示。

随着功能的完善,物品信息会逐步进行补充,如武器、材料等信息的添加。先以药品为例,txt文档信息的输入如下

1001,smallHpPotion,icon-potion1,Drug,40,0,40,60    //对应血药和蓝药
1002,bigHpPotion,icon-potion2,Drug,80,0,70,100
1003,smallMpPotion,icon-potion3,0,100,70,80
在GameSetting中新建一个脚本ObjectInfo管理物品,随时查找访问信息
using UnityEngine;
using System.Collections;
public class ObjectsInfo : MonoBehaviour {
    public static ObjectsInfo _instance;    //依旧用单例,方便随时访问
    void Awake()
    {
        _instance = this;
    }
    public enum ObjectType{    //三种用品的枚举
        Drug,
        Equip,
        Mat
    }
    public class ObjectInfo{    //单个物品的信息,可以进一步拆分成多个类,比如hp,mp只属于消耗品,可以单独成类
        public int id;
        public string name;
        public string icon_name;
        public ObjectType type;
        public int hp;
        public int mp;
        public int price_sell;
        public int price_buy;
    }
}
之后需要在程序中对txt中的文本信息进行读取,判断出物品并使用。
在GameSetting中添加一个类
public TextAsset ObjectInfoListText;
用来访问txt信息,将txt文件拖入

在GameSetting中用ReadInfo()读取物品信息,其中信息存储用字典完成
    using System.Collections.Generic;
    private Dictionary<int,ObjectInfo> objectInfoDict = new Dictionary<int, ObjectInfo> ();

    void ReadInfo(){
        string text = ObjectInfoListText.text;    //读取ObjectInfoListText中的文本
        string[] strArray = text.Split("\n");    //将读取到的文本以“\n”为标识拆分成数组,存储到strArray[]数组中
        foreach (string str in strArray) {     //将strArray[]数组中的数据以逗号为标识拆分成数组,存储到proArray[]数组中,即把所有txt中的物品信息存入字典
            string[] proArray = str.Split(",");    
            ObjectInfo info = new ObjectInfo();    //读取txt中的信息赋值给实例化的info
            int id = int.Parse(proArray[0]);    
            string name = proArray[1];
            string icon_name = proArray[2];
            string str_type = proArray[3];
            ObjectType type = ObjectType.Drug;    
            switch(str_type){    //根据读到的str_type进行type的设置
            case "Drug":
                type = ObjectType.Drug;
                break;
            case "Equip":
                type = ObjectType.Equip;
                break;
            case "Mat":
                type = ObjectType.Mat;
                break;
            }
            info.id=id;info.name=name;info.icon_name=icon_name;    //实例化ObjectInfo类,用以存储各项信息
            if(type = ObjectType.Drug)
            {
                int hp = int.Parse(proArray[4]);
                int mp = int.Parse(proArray[5]);
                int price_sell = int.Parse(proArray[6]);
                int price_buy = int.Parse(proArray[7]);
                info.hp=hp;info.mp=mp;info.price_sell=price_sell;info.price_buy=price_buy;    //实例化ObjectInfo类,用以存储各项信息
            }
            objectInfoDict.Add(id,info);    //数据存入字典中,注意,这里的id作为索引,用于访问对应物品信息,在外界进行访问时需要用到id,因此需要把id与info独立开来!
        }
    }
由于字典是private的,如果需要调用信息,可以提供一个接口,即
    public ObjectInfo GetObjectInfoFromDict(int id){
        ObjectInfo info = null;
        objectInfoDict.TryGetValue (id, out info);
        return info;
    }
即可在外界访问

5.3 背包系统的设计

在UI界面中新建一个Sprite,命名为Inventory,并导入网格,之后加入金币和金币数量(Label)显示。如下

为了在鼠标点击物品栏时角色不移动,对Inventory加入一个box collider即可。

因为背包是经常需要访问的,我们可以设置为单例模式,方便随时进行调用。在Inventory脚本中输入
    public static Inventory _instance;
    private TweenPosition tween;
    void Awake(){
        _instance = this;
    }
    public void Show()
    {
        tween.PlayForward ();
    }
    public void Hide()
    {
        tween.PlayReverse ();
    }
对Inventory脚本添加格子与金币信息等
using System.Collections.Generic;    //提供对List的支持
public List<InventoryItemGrid> itemGridList = new List<InventoryItemGrid>();    //用List存储网格信息
private int coinCount = 1000;    //金币信息
public UILabel coinNumberLabel;    //金币的显示

这些格子与金币信息添加成功后,我们要对每一个格子进行操作,进行物品的添加与使用
首先我们对网格添加一个Script Child作为Prefab,之后导入hp药素材进行初步设置,如下

在网格中要存储物品的外观信息、数量信息以及物品名信息,我们可以在InventoryItemGrid中进行管理。
using UnityEngine;
using System.Collections;
public class InventoryItemGrid : MonoBehaviour {
    private int id = 0;    //当前网格存储的物品对应id
    private ObjectsInfo .ObjectInfo info = null;
    private int num = 0;    //当前网格物品个数
    private UILabel numberLabel;    //显示物品个数的网格
    // Use this for initialization
    void Start () {
        numberLabel = this.GetComponentsInChildren<UILabel> ();    //取自自身子类的UILabel
    }
    
    public void SetId(int id,int num = 1){    //向网格中塞东西,添加物品的数量(number)默认为1
        info = ObjectsInfo._instance.GetObjectInfoFromDict (id);    //得到字典中的物品信息
        InventoryInsideItem item = this.GetComponent<InventoryInsideItem> ();    //实例化一个item,用以设置物品显示
        item.SetIconName (info.icon_name);    //设置item的物品名

        numberLabel.gameObject.SetActive (true);    //显示numberLabel
        this.num = num;    //形参中的num=1赋值给private int num
        numberLabel.text = this.num.ToString ();    // 给numberLabel赋值
    }
    public void ClearInfo()    //当物品进行拖动时,当前网格信息的清空
    {
        id = 0;
        info = null;
        num = 0;
        numberLabel.gameObject.SetActive (false);
    }
}
其中  item.SetIconName (info.icon_name); 是在InventoryInsideItem中的一个函数,实现设置item名称的作用,代码如下
    public void SetIconName(string icon_name)
    {
        sprite.spriteName = icon_name;
    }

总结:至此,(上)部分的内容就完成了,主要是一些基础界面和物品信息的创建,(下)部分将介绍背包中的各项功能。

猜你喜欢

转载自blog.csdn.net/s1314_jhc/article/details/79690154
今日推荐