• U3D 装备的添加和移除(Unity3D)


    本案例主要实现功能如下:
    1.创建UI界面,包含两个装备栏,四个武器选择栏以及显示人物的属性的文本框
    2.每一个装备都有自己的属性(AD/AP/AR/MP)
    3.人物也有自己的基础属性(AD/AP/AR/MP)
    4.可添加或移除装备到人物的装备栏中,最多两个
    5.丢弃装备后,可添加新的装备
    6.添加装备,人物的对应属性增加
    7.减少装备,人物的对应属性减少
    8.界面属性值和数据库中数据同步

    创建数据库,包括英雄(Hero)信息和装备(Equip)信息

    创建DataController脚本,用于封装一些数据库的操作
    该脚本为单例脚本,方便外部的调用.
    引入Mono.Data.Sqlite命名空间(需要在Project中导入Plugins文件夹,里面含有对应的dll文件)

    将脚本写为单例脚本
    //单例脚本
        public static DataController Instance;
    void Awake ()
        {
            Instance = this;
        }
    
    脚本中声明是的字段
    //数据库对象
        SqliteConnection connection;
        SqliteCommand command;
        SqliteDataReader reader;
        //数据库路径
        string sqlitePath;
    
    1.创建数据库连接并打开数据库
    /// <summary>
        /// 连接数据库方法
        /// </summary>
        /// <param name="DBName">数据库名称</param>
    public void ConnectToSqlite (string DBName)
        {
            //如果不包含.sqlite  添加
            if (!DBName.Contains (".sqlite")) {
                DBName += ".sqlite";
            }
            //数据库路径配置
            sqlitePath = "Data Source =" + Application.streamingAssetsPath + "/" + DBName;
            //创建数据库连接对象
            connection = new SqliteConnection (sqlitePath);
            //创建数据了库命令对象
            command = connection.CreateCommand ();
            try {
                //打开数据库
                connection.Open ();
            } catch (System.Exception ex) {
                //异常信息
                Debug.Log (ex.Message);
            }
        }
    
    2.关闭数据库方法
    public void CloseSqliteConnection ()
        {
            try {
                //在数据库打开的前提下
                if (connection != null) {
                    //关闭数据库
                    connection.Close ();
                }
            } catch (System.Exception ex) {
                //异常信息
                Debug.Log (ex.Message);
            }
        }
    
    3.查询属性的基本信息(人物或装备)
    /// <summary>
        /// 查询属性的基本信息
        /// </summary>
        /// <returns>返回查询的结果(float数组)</returns>
        /// <param name="isHero">true:表示查询的某个英雄的信息
        ///                 false:查询某个装备的信息
        /// <param name="name">传入查询对象的方法</param>
        public float[] SelectProPertyInfo (bool isHero, string name)
        {
            try {
                //用于存储查询到的信息(AD/AP/AR/MP)
                float[] result = new float[4];
                //查询语句
                string sql;
                if (isHero) {
                    //如果查询的是英雄
                    sql = "select AD,AP,AR,MP from Hero where HeroName='" + name + "'";
                } else {
                    sql = "select AD,AP,AR,MP from Equip where EquipName='" + name + "'";
                }
                //将SQL语句赋值给命令对象
                command.CommandText = sql;
                //执行语句
                reader = command.ExecuteReader ();
                //只读取一行
                reader.Read ();
                for (int i = 0; i < reader.FieldCount; i++) {
                    //逐个获取字段值,存入数组
                    result [i] = System.Convert.ToSingle (reader.GetValue (i));
                }
                reader.Close ();
                return result;
            } catch (System.Exception ex) {
                Debug.Log (ex.Message);
                return null;
            }
        }
    
    4.当添加或移除装备,人物信息的变化
    /// <summary>
        /// 添加或移除装备
        /// </summary>
        /// returns:当添加或移除装备后对应英雄变化后的数据
        /// <param name="isAdd" true:添加  false:移除装备
        /// <param name="heroInfo  要添加或移除装备的英雄信息
        /// <param name="equipInfo  要添加或移除的装备信息
        public float[] AddOrRemoveProperty (bool isAdd, float[] heroInfo, float[] equipInfo)
        {
            try {
                if (heroInfo.Length == 4 && equipInfo.Length == 4) {
                    //声明存放运算结果的数组
                    float[] result = new float[4];
                    if (isAdd) {
                        //将两个数组的元素相加
                        for (int i = 0; i < result.Length; i++) {
                            result [i] = heroInfo [i] + equipInfo [i];
                        }
                    } else {
                        //移除装备
                        for (int i = 0; i < result.Length; i++) {
                            result [i] = heroInfo [i] - equipInfo [i];
                        }
                    }
                    return result;
                }
                //参数不合法
                return null;
            } catch (System.Exception ex) {
                Debug.Log (ex.Message);
                return null;
            }
        }
    5.更新英雄信息到数据库,修改信息后要将新的信息更新到数据库中
    /// <summary>
        /// 更新英雄信息到数据库
        /// </summary>
        /// <param name="newHeroInfo" 更新后的英雄信息
        /// <param name="heroName"> 更新信息英雄名
        public void UpdateHeroPropety (float[] newHeroInfo, string heroName)
        {
            try {
                string sql = "update Hero set AD=" + newHeroInfo [0] + ",AP=" + newHeroInfo [1] + ",AR=" + newHeroInfo [2]+ ",MP=" + newHeroInfo [3] + " " + "where HeroName='" + heroName + "'";
                command.CommandText = sql;
                command.ExecuteNonQuery ();
            } catch (System.Exception ex) {
                Debug.Log (ex.Message);
            }
        }
    
    
    在商店物品栏的父物体Shop上添加AddEquipScript脚本,实现点击装备对应的按钮后添加对应的装备到装备栏上,并修改人物的属性,跟新UI界面的显示.
    
    脚本中定义的字段
    //更新英雄信息的脚本
        HeroInfoDisplayScript heroInfoScr;
        //装备栏上的脚本
        EquipBoxesScript equipInfoScr;
    
    在Start方法中初始化字段
    void Start ()
        {
            heroInfoScr = GameObject.Find ("HeroInfoText").GetComponent<HeroInfoDisplayScript> ();
            equipInfoScr = GameObject.Find ("EquipBoxes").GetComponent<EquipBoxesScript> ();
        }
    
    添加按钮点击响应事件
    /// <summary>
        /// 点击背包中的装备按钮,给英雄添加装备
        /// </summary>
        /// <param name="btn">Button.</param>
        public void AddEquipBtnAction (GameObject btn)
        {
            int index = equipInfoScr.CanAddEquip ();
            if (index != -1) {
                //说明当前有空的装备栏,可以添加
                //1.先获取到点击要添加的图片
                Sprite equipImg = btn.GetComponent<Image> ().sprite;
                //2.将添加的按钮的图片赋值给装备栏中按钮
                equipInfoScr.transform.GetChild (index).GetComponent<Image> ().sprite = equipImg;
                //根据添加的装备名字查找这个装备
                string equipName = btn.name;
                //打开数据库
                DataController.Instance.ConnectToSqlite ("LOL");
                //找到装备信息
                float[] equipDatas = DataController.Instance.SelectProPertyInfo (false, equipName);
                // 找到英雄信息
                float[] heroDatas = DataController.Instance.SelectProPertyInfo (true, "EZ");
                //为英雄添加装备信息
                float[] newHweoDatas = DataController.Instance.AddOrRemoveProperty (true, heroDatas, equipDatas);
                //跟新信息到数据库
                DataController.Instance.UpdateHeroPropety (newHweoDatas, "EZ");
                //更新UI
                heroInfoScr.DisplayHeroInfo (newHweoDatas);
                //关闭数据库
                DataController.Instance.CloseSqliteConnection ();
            }
        }
    
    在装备栏父物体上添加EquipBoxesScript脚本,控制装备栏中两个装备按钮的点击,主要是移除装备,并且减少英雄的属性,以及对外判断是否以继续添加装备,(在退出时记住装备栏中的装备,在程序重新加载时保持原状)
    
    脚本中定义的字段
    //默认装备栏图片
        public Sprite defaultPic;
        //英雄属性的脚本
        HeroInfoDisplayScript heroInfoScr;
        //所有的装备
        public Sprite[] equipPics;
    
    在Start方法中初始化
    void Start ()
        {
            //获得展示英雄信息的脚本
            heroInfoScr = GameObject.Find ("HeroInfoText").GetComponent<HeroInfoDisplayScript> ();
            ShowImg ();
        }
    
    添加或者移除装备
    //添加装备栏中按钮时,如果该装备栏有装备,则移除装备
        //同时更新英雄属性展示,以及更新数据库英雄数据
        //参数equip:表示点击的是哪个装备按钮
        public void RemoveEquipBtnAction (GameObject equipbtn)
        {
            //装备的默认图片,(即没有装备时的图片)
            string defaultName = "InputFieldBackground";
            //如果点击的当前按钮的图片不是默认图片的名字
            //就表示当前点击的按钮是有装备的,执行移除装备操作
            if (equipbtn.GetComponent<Image> ().sprite.name
                != defaultName) {
                //获取当前按钮上展示的装备图片的名字
                string equipName = equipbtn.GetComponent<Image> ().sprite.name;
                //移除该装备,即将该装备按钮上的图片更换成默认
                equipbtn.GetComponent<Image> ().sprite = defaultPic;
                // 开始更新数据库英雄的数据(因为装备移除了)
                DataController.Instance.ConnectToSqlite ("LOL");
                //查询当前移除的装备信息
                float[] equipDatas = DataController.Instance.SelectProPertyInfo (false, equipName);
                //查询当前操作的英雄信息
                float[] heroDatas = DataController.Instance.SelectProPertyInfo (true, "EZ");
                //更新数据后的英雄信息
                float[] newHeroInfos = DataController.Instance.AddOrRemoveProperty (false, heroDatas, equipDatas);
                //将更新后的英雄信息存储到数据库中
                DataController.Instance.UpdateHeroPropety (newHeroInfos, "EZ");
                //更新UI界面英雄信息展示
                heroInfoScr.DisplayHeroInfo (newHeroInfos);
                //关闭数据库
                DataController.Instance.CloseSqliteConnection ();
            }
        }
    
    判断是否可以添加装备
    public int CanAddEquip ()
        {
            //获取装备上的图片名称
            string equip0 = transform.GetChild (0).GetComponent<Image> ().sprite.name;
            string equip1 = transform.GetChild (1).GetComponent<Image> ().sprite.name;
            //图片的默认名字
            string defaultName = "InputFieldBackground";
            if (defaultName == equip0) {
                return 0;
            } else if (defaultName == equip1) {
                return 1;
            } else {
                //不可以添加装备了
                return -1;
            }
        }

    保留图片
    方法一:使用PlayerPrefs将已有的图片信息存到本地

    方法二:在数据库中创建一个表用来存储图片信息

    具体的存,取功能 的实现与PlayerPrefs相同

    在场景中HeroInfoText上添加脚本用来控制在脚本中显示英雄的基本信息

    //获得要展示英雄数据的Text
        Text infoText;
    
        void Start ()
        {
            infoText = GetComponent<Text> ();
            //展示英雄数据
            //1.打开数据库
            DataController.Instance.ConnectToSqlite ("LOL");
            //2.查询英雄数据
            float[] infos = DataController.Instance.SelectProPertyInfo (true, "EZ");
            //展示英雄信息到heroInfoText上
            DisplayHeroInfo (infos);
            //关闭数据库
            DataController.Instance.CloseSqliteConnection ();
        }
    
        /// <summary>
        /// 展示英雄信息
        /// </summary>
        /// <param name="info">要展示的数据</param>
        public void DisplayHeroInfo (float[] info)
        {
            infoText.text = 
            "攻击力: " + info [0] + "
    " +
            "法强: " + info [1] + "
    " +
            "护甲值: " + info [2] + "
    " +
            "魔抗值: " + info [3];
        }
  • 相关阅读:
    10. Regular Expression Matching
    Leetcode:9. Palindrome Number
    MySQL
    MyBatis Plus 自动类型转换之TypeHandler
    深拷贝和浅拷贝
    【强制】不要在程序中写死一年为 365 天,避免在公历闰年时出现日期转换错误或程序逻辑 错误。
    【强制】日期格式化时,传入 pattern 中表示年份统一使用小写的 y。
    【推荐】循环体内,字符串的连接方式,使用 StringBuilder 的 append 方法进行扩展。
    【强制】POJO如果继承了另一个 POJO 类,注意在前面加一下 super.toString。
    【强制】禁止使用构造方法 BigDecimal(double)的方式把 double 值转化为 BigDecimal 对象。
  • 原文地址:https://www.cnblogs.com/zpy1993-09/p/11818077.html
Copyright © 2020-2023  润新知