Unity笔记-25-简单的商城系统&数据库操作
Posted 韩天衣
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Unity笔记-25-简单的商城系统&数据库操作相关的知识,希望对你有一定的参考价值。
Unity笔记-25-简单的商城系统&数据库操作
要求与分析
英雄属性界面
展示英雄头像,英雄名称,英雄属性(AD,AP,AR,SR,自左向右,自上向下),金币数量
商店界面
展示可购买的物品,点击即可购买
背包界面
展示背包中的五瓶,点击即可出售
数据库(数据库为**Sqlite
**本地数据库)
英雄表:存储英雄名称,英雄属性,金币数量,背包物品
商店表:存储物品名称,物品属性,物品价格
UI搭建
运行完成图展示
UI对象的父子级关系如图。英雄属性,Bag
,Shop
添加了布局组件以方便网格布局。
自上而下分别为:英雄头像,英雄名称,英雄属性图,英雄属性值,金币数量,背包,商店
脚本模块
数据库部分
数据库功能&一次封装
提供数据库的基本功能:开启,关闭,更新,插入等方法
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Mono.Data.Sqlite;
public class DatabaseFrame
{
//单例
#region Single
private static DatabaseFrame instance;
public static DatabaseFrame GetInstance()
{
if (instance == null)
{
instance = new DatabaseFrame();
}
return instance;
}
protected DatabaseFrame() { }
#endregion
public SqliteConnection con;
public void OpenDatabase(string databaseName)
{
string connectPath;
if (!databaseName.EndsWith(".sqlite"))
{
databaseName += ".sqlite";
}
#if UNITY_EDITOR
connectPath = "Data Source = " + Application.streamingAssetsPath + "/" + databaseName;
#endif
con = new SqliteConnection(connectPath);
con.Open();
}
public void CloseDatabase(SqliteConnection con,SqliteCommand command,SqliteDataReader reader)
{
if (con != null)
{
con.Close();
con = null;
}
if (command != null)
{
command.Dispose();
command = null;
}
if (reader != null)
{
reader.Close();
reader = null;
}
}
public int ModifyData(SqliteCommand command,string query)
{
command.CommandText = query;
return command.ExecuteNonQuery();
}
public object SelectSingleData(SqliteCommand command,string query)
{
command.CommandText = query;
return command.ExecuteScalar();
}
public List<ArrayList> SelectMultipleData(SqliteCommand command,SqliteDataReader reader,string query)
{
command.CommandText = query;
reader = command.ExecuteReader();
List<ArrayList> results = new List<ArrayList>();
while (reader.Read())
{
ArrayList currentRow = new ArrayList();
for(int i = 0; i < reader.FieldCount; i++)
{
currentRow.Add(reader.GetValue(i));
}
results.Add(currentRow);
}
return results;
}
}
商店数据库&二次封装
继承DatabaseFrame
类,也就是继承一次封装的类
在数据库的基础上,提供购买装备,出售装备,获得英雄属性,获取物品属性等数据库层面上的操作
其次,数据表需要提前定义映射类,方便数据接收
英雄表-背包物品使用格式:**|装备名称|装备名称
**通过‘|‘隔开,在通过字符串的拆解判断
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Mono.Data.Sqlite;
namespace ShopJDBC
{
public class ShopFrame : DatabaseFrame
{
#region Single
private static ShopFrame instance;
//这里的new修饰符可以是的此方法覆盖调父类的同名方法或者属性
public static new ShopFrame GetInstance()
{
if (instance == null)
{
instance = new ShopFrame();
}
return instance;
}
private ShopFrame()
{
}
#endregion
/// <summary>
/// 买装备
/// </summary>
/// <param name="heroName">英雄名称</param>
/// <param name="equipName">装备名称</param>
public void BuyEquip(string heroName, string equipName)
{
HeroTable hero = GetHeroProperties(heroName);
if (hero.heroEquips.Split('|').Length > 8)
{
Debug.Log("No BagBox");
return;
}
EquipTable equip = GetEquipProperties(equipName);
if (hero.heroMoney < equip.equipCost)
{
Debug.Log("Money is not enough");
return;
}
hero.heroMoney -= equip.equipCost;
PropertiesOperation(hero, equip, 1);
EquipOperation(hero, equipName);
UpdateHeroTable(hero);
}
/// <summary>
/// 卖装备
/// </summary>
/// <param name="heroName">英雄名称</param>
/// <param name="equipName">装备名称</param>
/// <param name="equipIndex">装备位置</param>
public void SellEquip(string heroName, string equipName, int equipIndex)
{
HeroTable hero = GetHeroProperties(heroName);
EquipTable equip = GetEquipProperties(equipName);
hero.heroMoney += equip.equipCost;
PropertiesOperation(hero, equip, 2);
EquipOperation(hero, equipName, equipIndex);
UpdateHeroTable(hero);
}
/// <summary>
/// 获得装备属性
/// </summary>
/// <param name="equipName">装备名称</param>
/// <returns></returns>
public EquipTable GetEquipProperties(string equipName)
{
SqliteCommand command = con.CreateCommand();
SqliteDataReader reader = null;
string query = "Select * from Shop where equipName='" + equipName + "'";
List<ArrayList> result = SelectMultipleData(command, reader, query);
CloseDatabase(null, command, reader);
return new EquipTable(System.Convert.ToString(result[0][0]), System.Convert.ToInt32(result[0][1]), System.Convert.ToInt32(result[0][2]), System.Convert.ToInt32(result[0][3]), System.Convert.ToInt32(result[0][4]), System.Convert.ToInt32(result[0][5]));
}
/// <summary>
/// 获得英雄属性
/// </summary>
/// <param name="heroName">英雄名称</param>
/// <returns></returns>
public HeroTable GetHeroProperties(string heroName)
{
SqliteCommand command = con.CreateCommand();
SqliteDataReader reader = null;
string query = "Select * from Hero where heroName='" + heroName + "'";
List<ArrayList> result = SelectMultipleData(command, reader, query);
HeroTable hero = new HeroTable(System.Convert.ToString(result[0][0]), System.Convert.ToInt32(result[0][1]), System.Convert.ToInt32(result[0][2]), System.Convert.ToInt32(result[0][3]), System.Convert.ToInt32(result[0][4]), System.Convert.ToInt32(result[0][5]), System.Convert.ToString(result[0][6]));
if (hero.heroEquips == "NULL")
{
hero.heroEquips = "";
}
CloseDatabase(null, command, reader);
return hero;
}
/// <summary>
/// 更新英雄数据
/// </summary>
/// <param name="hero"></param>
public void UpdateHeroTable(HeroTable hero)
{
SqliteCommand command = con.CreateCommand();
string query = "Update Hero Set heroMoney=" + hero.heroMoney + ",ADProperty=" + hero.AD + ",APProperty=" + hero.AP + ",ARProperty=" + hero.AR + ",SRProperty=" + hero.SR + ",heroEquips='" + hero.heroEquips + "' where heroName='" + hero.heroName + "'";
ModifyData(command, query);
CloseDatabase(null, command, null);
}
/// <summary>
/// 英雄-装备-属性操作
/// </summary>
/// <param name="hero">英雄</param>
/// <param name="equip">装备</param>
/// <param name="operationID">操作编号</param>
public void PropertiesOperation(HeroTable hero, EquipTable equip, int operationID)
{
if (operationID == 1)
{
hero.AD += equip.AD;
hero.AP += equip.AP;
hero.AR += equip.AR;
hero.SR += equip.SR;
}
else if (operationID == 2)
{
hero.AD -= equip.AD;
hero.AP -= equip.AP;
hero.AR -= equip.AR;
hero.SR -= equip.SR;
}
}
/// <summary>
/// 英雄-装备-装备操作
/// </summary>
/// <param name="hero">英雄</param>
/// <param name="equipName">装备名称</param>
/// <param name="equipIndex">装备位置,不填则为空</param>
public void EquipOperation(HeroTable hero, string equipName, int? equipIndex = null)
{
if (equipIndex == null)
{
hero.heroEquips += "|" + equipName;
}
else
{
hero.heroEquips = RemoveEquip(hero.heroEquips, 1) == "" ? "NULL" : RemoveEquip(hero.heroEquips, equipIndex.Value);
}
}
/// <summary>
/// 字符串-移除装备
/// </summary>
/// <param name="root"></param>
/// <param name="valueIndex"></param>
/// <returns></returns>
public string RemoveEquip(string root, int valueIndex)
{
int index = 0;
int endIndex = 0;
for (int i = 0; i < valueIndex; i++)
{
index = root.IndexOf("|", index) + 1;
}
endIndex = root.IndexOf("|", index) != -1 ? root.IndexOf("|", index) : root.Length;
root = root.Substring(0, index - 1) + root.Substring(endIndex);
return root;
}
/// <summary>
/// 获取所有装备信息
/// </summary>
/// <returns></returns>
public List<EquipTable> GetEquips()
{
List<EquipTable> allEquip = new List<EquipTable>();
SqliteCommand command = con.CreateCommand();
SqliteDataReader reader = null;
string query = "Select * from Shop";
List<ArrayList> equips = SelectMultipleData(command, reader, query);
for (int i = 0; i < equips.Count; i++)
{
EquipTable equip = new EquipTable(System.Convert.ToString(equips[i][0]), System.Convert.ToInt32(equips[i][1]), System.Convert.ToInt32(equips[i][2]), System.Convert.ToInt32(equips[i][3]), System.Convert.ToInt32(equips[i][4]), System.Convert.ToInt32(equips[i][5]));
allEquip.Add(equip);
}
return allEquip;
}
}
public class HeroTable
{
public string heroName;
public int heroMoney;
public int AD;
public int AP;
public int AR;
public int SR;
public string heroEquips;
public HeroTable(string heroName, int heroMoney, int AD, int AP, int AR, int SR, string heroEquips)
{
this.heroName = heroName;
this.heroMoney = heroMoney;
this.AD = AD;
this.AP = AP;
this.AR = AR;
this.SR = SR;
this.heroEquips = heroEquips;
}
}
public class EquipTable
{
public string equipName;
public int equipCost;
public int AD;
public int AP;
public int AR;
public int SR;
public EquipTable(string equipName, int equipCost, int AD, int AP, int AR, int SR)
{
this.equipName = equipName;
this.equipCost = equipCost;
this.AD = AD;
this.AP = AP;
this.AR = AR;
this.SR = SR;
}
}
}
UI部分
UI界面
提供UI界面的所有初始化操作,购买或者出售后的更新操作
其余请看代码注释
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using ShopJDBC;
public class ShopView : MonoBehaviour
{
private ShopFrame shop;
private Transform shopWindow;
private Transform bagWindow;
private List<EquipTable> equips;
private GameObject shopPerfabs;
private GameObject bagPerfabs;
private HeroTable hero;
Transform propertiesParent;
private List<Text> propertiesList;
private void Awake()
{
shop = ShopFrame.GetInstance();
UI_Init();
}
private void Start()
{
shop.OpenDatabase("ShopDatabase");
HeroInitOrUpdate();
BagInitOrUpdate();
ShopInit();
}
/// <summary>
/// UI初始化
/// </summary>
private void UI_Init()
{
shopWindow = transform.Find("Shop");
shopPerfabs = Resources.Load<GameObject>("ShoppingCenterTest/Prefabs/ShopBox");
bagWindow = transform.Find("Bag");
bagPerfabs = Resources.Load<GameObject>("ShoppingCenterTest/Prefabs/BagBox");
propertiesParent = transform.Find("HeroPropertiesText");
propertiesList = new List<Text>();
propertiesList.Add(transform.Find("HeroNameText").GetComponent<Text>());
propertiesList.Add(propertiesParent.GetChild(0).GetComponent<Text>());
propertiesList.Add(propertiesParent.GetChild(1).GetComponent<Text>());
propertiesList.Add(propertiesParent.GetChild(2).GetComponent<Text>());
propertiesList.Add(propertiesParent.GetChild(3).GetComponent<Text>());
propertiesList.Add(transform.Find("Money").GetChild(0).GetComponent<Text>());
}
/// <summary>
/// 获取精灵
/// </summary>
/// <param name="SpriteName">精灵名称</param>
/// <returns></returns>
private Sprite GetSprite(string SpriteName)
{
return Resources.Load<Sprite>("ShoppingCenterTest/Icon/"+SpriteName);
}
/// <summary>
/// 商店初始化
/// </summary>
private void ShopInit()
{
equips = shop.GetEquips();
for(int i = 0; i < equips.Count; i++)
{
GameObject shopbox = Instantiate(shopPerfabs);
shopbox.GetComponent<ShopButton>().Init(hero.heroName,equips[i]);
shopbox.GetComponent<ShopButton>().viewUpdate += HeroUpdate;
shopbox.transform.SetParent(shopWindow.GetChild(i));
shopbox.transform.localPosition = Vector3.zero;
shopbox.transform.localScale = Vector3.one;
shopbox.GetComponent<Image>().sprite = GetSprite(equips[i].equipName);
}
}
/// <summary>
/// 英雄属性初始化或者更新
/// </summary>
private void HeroInitOrUpdate()
{
hero = shop.GetHeroProperties("SKT_Faker");
propertiesList[0].text = hero.heroName;
propertiesList[1].text = hero.AD.ToString();
propertiesList[2].text = hero.AP.ToString();
propertiesList[3].text = hero.AR.ToString();
propertiesList[4].text = hero.SR.ToString();
propertiesList[5].text = hero.heroMoney.ToString();
}
/// <summary>
/// 背包初始化
/// </summary>
private void BagInitOrUpdate()
{
string[] heroEquips = hero.heroEquips.Split('|');
for (int i = 1; i < heroEquips.Length; i++)
{
GameObject bagbox = Instantiate(bagPerfabs);
bagbox.GetComponent<BagButton>().Init(hero.heroName,heroEquips[i],i);
bagbox.GetComponent<BagButton>().viewUpdate += HeroUpdate;
bagbox.transform.SetParent(bagWindow.GetChild(i - 1));
bagbox.transform.localPosition = Vector3.zero;
bagbox.transform.localScale = Vector3.one;
bagbox.GetComponent<Image>().sprite = GetSprite(heroEquips[i]);
}
}
/// <summary>
/// 背包更新
/// </summary>
private void BagUpdate()
{
string[] heroEquips = hero.heroEquips.Split('|');
for(int i = 1; i < heroEquips.Length; i++)
{
if (bagWindow.GetChild(i - 1).childCount != 0)
{
Transform bagbox = bagWindow.GetChild(i - 1).GetChild(0);
bagbox.GetComponent<BagButton>().Init(hero.heroName, heroEquips[i], i);
bagbox.GetComponent<Image>().sprite = GetSprite(heroEquips[i]);
}
else
{
GameObject bagbox = Instantiate(bagPerfabs);
bagbox.GetComponent<BagButton>().Init(hero.heroName, heroEquips[i], i);
bagbox.GetComponent<BagButton>().viewUpdate += HeroUpdate;
bagbox.transform.SetParent(bagWindow.GetChild(i - 1));
bagbox.transform.localPosition = Vector3.zero;
bagbox.transform.localScale = Vector3.one;
bagbox.GetComponent<Image>().sprite = GetSprite(heroEquips[i]);
}
}
for (int i = heroEquips.Length; i <= 8; i++)
{
if (bagWindow.GetChild(i - 1).childCount != 0)
Destroy(bagWindow.GetChild(i-1).GetChild(0).gameObject);
}
}
/// <summary>
/// 面板更新
/// </summary>
private void HeroUpdate()
{
HeroInitOrUpdate();
BagUpdate();
}
/// <summary>
/// 退出
/// </summary>
private void OnApplicationQuit()
{
shop.CloseDatabase(shop.con, null, null);
}
}
装备按钮(商店&背包)
Shop下的装备按钮
唯一需要说明的是:UI界面的更新,需要通过装备按钮脚本的事件绑定UI界面脚本里的更新方法,再操作完购买或者出售的时候更新面板
另外在鼠标进入装备按钮,会显示装备的名称,价格,属性,通过鼠标事件实现
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using ShopJDBC;
using System;
using UnityEngine.EventSystems;
using Random = System.Random;
public class ShopButton : MonoBehaviour,IPointerEnterHandler,IPointerExitHandler
{
public Action viewUpdate;
public string heroName;
public EquipTable equip;
private Button button;
private GameObject tipPrefab;
private GameObject tip;
private Random random;
private Transform parent;
private Transform ShopWindow;
private void Awake()
{
random = new Random();
button = transform.GetComponent<Button>();
button.onClick.AddListener(OnChick);
tipPrefab= Resources.Load<GameObject>("ShoppingCenterTest/Prefabs/Tip");
}
private void Start()
{
parent = transform.parent;
ShopWindow = parent.parent;
}
public void Init(string heroName,EquipTable equip)
{
this.heroName = heroName;
this.equip = equip;
}
public void OnChick()
{
ShopFrame.GetInstance().BuyEquip(heroName, equip.equipName);
viewUpdate();
}
public void OnPointerEnter(PointerEventData eventData)
{
tip = Instantiate(tipPrefab);
//tip.GetComponent<Image>().color = new Color(random.Next(0,255)/255f,random.Next(0,255)/255f,random.Next(0,255)/255f,0.2f);
tip.transform.position =new Vector3(parent.position.x,parent.position.y,parent.position.z);
tip.transform.SetParent(ShopWindow);
tip.transform.GetChild(0).GetComponent<Text>().text = equip.equipName;
tip.transform.GetChild(1).GetComponent<Text>().text = "Cost:"+equip.equipCost.ToString();
tip.transform.GetChild(2).GetComponent<Text>().text = "AD:"+equip.AD.ToString();
tip.transform.GetChild(3).GetComponent<Text>().text = "AP:"+equip.AP.ToString();
tip.transform.GetChild(4).GetComponent<Text>().text = "AR"+equip.AR.ToString();
tip.transform.GetChild(5).GetComponent<Text>().text = "SR"+equip.SR.ToString();
}
public void OnPointerExit(PointerEventData eventData)
{
Destroy(tip);
tip = null;
}
}
Bag下的装备按钮
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using ShopJDBC;
using System;
public class BagButton : MonoBehaviour
{
public Action viewUpdate;
public string heroName;
public string equipName;
public int buttonIndex;
private Button button;
private void Awake()
{
button = transform.GetComponent<Button>();
button.onClick.AddListener(OnChick);
}
public void Init(string heroName,string equipName,int index)
{
this.heroName = heroName;
this.equipName = equipName;
this.buttonIndex = index;
}
public void OnChick()
{
ShopFrame.GetInstance().SellEquip(heroName,equipName,buttonIndex);
viewUpdate();
}
}
以上是关于Unity笔记-25-简单的商城系统&数据库操作的主要内容,如果未能解决你的问题,请参考以下文章