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();
}
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/344385.html
標籤:其他
上一篇:聚烷撐乙二醇(數學+期望)
下一篇:【游戲客戶端】實作刮刮樂效果
