遊戲中數據庫的設計、類的管理

前言:數據庫在遊戲中的應用
在(客戶端)Unity 需引入
在這裏插入圖片描述

在遊戲開發中,有的時候會因爲數據庫的設計而頭疼,作者最近在做一個 類似 VS 編輯器的項目,因爲 數據庫和 ADO 困惑了很久,快炸了,天天抓狂(頭髮還有),做着做着今天晚上豁然開朗了,當然後面有一個 主程大佬帶飛,很幸運,接下來將會記錄數據庫的設計方式、還有就是 C# 中連接數據庫、查詢數據庫中的內容、數據庫的結構類的寫法:

首先我們項目需要實現的功能就是:
在這裏插入圖片描述

在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述

這裏是有三個類的(Student,Teacher,Teaching)這裏我只分析一種,也就是 Student
首先可以看到右上角的問題描述,對應着不同的類,當類圖發生改變的時候,文字描述也會開始進行改變,緊接着甲方(老闆)需要做的事情就是我們(甲方)根據類圖格式來填空(UI 界面比較簡單 請忽略謝謝),右邊代碼框中留出來的 Button 按鈕就是需要進行補充的,具體補充的內容就不說了,帶過了,每次在代碼框中點擊了一次之後 在類圖下面的 框框中輸入 內容,然後根據用戶輸入的內容 跟數據庫中的內容進行對比(稍後會曝光數據庫的設計),如果說用戶輸入的內容和數據庫中的內容相同的時候,就開始對比寫下一個,反之跟數據庫中的內容不相同的時候,將用戶輸入的值(也就是代碼框中填充的代碼)變爲紅色;輸入正確以後也就是需要用戶輸入第二個值,再去跟數據庫中的內容進行對比,以此類推,一直比到最後,全部比完以後右下角的結果框中 出現一個運行的結果,當用戶點擊了 (默認的時候是沒有辦法進行點擊的)提交併運行的時候,保存 中間代碼框中的文本,並且生成 Java 格式的代碼(我不知道爲神馬要用 C# 去生成 Java代碼,反正甲方給的需求是這樣的)並且保存在 Assets文件夾下,最後打包成 WebGL 的包發佈到網頁上,緊接着拿着這個東西到 Java 搭建的服務器上面去運行…我也是醉了,
最後筆者簡單的算了算 Unity 、WebGL 、 MySql 、 服務器 涉及到 4 個端,筆者這個項目虧死,害,不過既然接了,就當學習一下,畢竟 吃一塹長一智。。。。
接下來上數據庫的設計以及代碼:
在這裏插入圖片描述
在這裏插入圖片描述
緊接着上 在 C# 中連接以及訪問數據庫的類了:

//==========================
// - FileName:      MySqlHelp.cs         
// - Created:       true.	
// - CreateTime:    2020/04/26 15:27:04	
// - Email:         [email protected]		
// - Region:        China WUHAN	
// - Description:   數據庫工具類 、 MysqlHelp 封裝在 GameManager 中,由於作者比較喜歡用大單例
//==========================
using MySql.Data.MySqlClient;
using System;
using System.Collections.Generic;
using System.Data;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using UnityEngine;

public class MySqlHelp
{
    private MySqlConnection mySqlConnection;
    private string _host;
    private string _id;
    private string _pwd;
    private string _dataBase;
    private string tableName = "user";
    private string configPath;

    public MySqlHelp()
    {
    	//寫入配置文件中  localhost|root|123456|codedb
        configPath = Application.dataPath + "/Config/Config.txt";
        string configStr = File.ReadAllText(configPath);
        string[] sqlStr = configStr.Split(new char[] { '|' });
        InitMySql(sqlStr[0], sqlStr[1], sqlStr[2], sqlStr[3]);
    }

    private void InitMySql(string host, string id, string pwd, string dataBase)
    {
        _host = host;
        _id = id;
        _pwd = pwd;
        _dataBase = dataBase;
        OpenSqlConnection();
    }

    /// <summary>
    /// 打開數據庫連接
    /// </summary>
    public void OpenSqlConnection()
    {
        string str = "";
        try
        {
            str = string.Format("Database={0};DataSource={1};User Id={2};Password={3};character set = utf8", _dataBase, _host, _id, _pwd, "3306");
            mySqlConnection = new MySqlConnection(str);
            mySqlConnection.Open();
            //Debug.Log("Mysql Connection Access");
            Debug.Log("數據庫連接成功");
        }
        catch (Exception e)
        {
            Debug.LogError(e.Message);
            //Debug.LogError("MySqlAccess", "OpenSql() 服務器連接失敗。 connect str={0};Error:{1}", str, e.Message);
        }
    }

    public DataSet Query(string format, params object[] args)
    {
        string query = string.Format(format, args);
        //Debuger.Log("MySqlAccess", "Query() query={0}", query);
        //Debug.Log(e.Message);
        return ExecuteQuery(query);
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="sql"></param>
    /// <param name="tableName">虛擬表名稱</param>
    /// <returns></returns>
    private DataSet ExecuteQuery(string sql)
    {
        //Debug.Log(sql+"____");
        if (mySqlConnection.State == ConnectionState.Open)
        {
            DataSet ds = new DataSet();
            try
            {
                MySqlCommand mySqlCommand = new MySqlCommand(sql, mySqlConnection);
                MySqlDataAdapter mySqlDataAdapter = new MySqlDataAdapter(mySqlCommand);
                mySqlDataAdapter.Fill(ds);
            }
            catch (Exception e)
            {
                Debug.LogError(e.Message);
                //Debuger.LogError("MySqlHelper", "ExecuteQuery() sql={0} Error:{1}", sql, e.Message);
            }
            return ds;
        }
        return null;
    }


    public int ExcuteReader(string sqlTxt)
    {
        if (mySqlConnection.State == ConnectionState.Open)
        {
            try
            {
                Debug.Log(sqlTxt);
                MySqlCommand cmd = new MySqlCommand(sqlTxt, mySqlConnection);
                return cmd.ExecuteNonQuery();
            }
            catch (Exception ex)
            {
                Debug.LogError(ex.Message);
                return 0;
            }
        }
        return 0;
    }

    /// <summary>
    /// 釋放連接
    /// </summary>
    public void Close()
    {
        if (mySqlConnection != null)
        {
            mySqlConnection.Close();
            mySqlConnection.Dispose();
            mySqlConnection = null;
        }
    }

}

然後的話就是本項目的重點,也就是核心類(作者摸了好久,一直不懂用法):本來是有點捨不得分享,但是爲了學習更多大牛的方法,豁出去了

//==========================
// - FileName:      MainPanel.cs         
// - Created:       true.	
// - CreateTime:    2020/04/26 15:27:04	
// - Email:         [email protected]		
// - Region:        China WUHAN	
// - Description:   數據庫結構類
//==========================
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class UserDoItemData
{
    //數據庫正確ID
    public int classID;
    //數據庫正確答案
    public string okText;
    //數據庫提示信息
    public string okMessage;

    //用戶輸入的答案
    public string userInputText = "";

    public UserDoItemData(int id, string oktxt,string msg)
    {
        classID = id;
        okText = oktxt;
        okMessage = msg;
    }
}

然後的話就是從數據庫中取數據的一些方法:

private void InitEvent()
{
        #region 實驗
        //打開數據庫中的表                                           封裝好的方法.......
        DataSet dataSet = gameManager.mysqlHelp.Query("select * from maincontent", "");    //select * from classstructtable
        DataTable dataTable = dataSet.Tables[0];
        DataRow _dr;
        for (int i = 0; i < dataTable.Rows.Count; i++)
        {
            _dr = dataTable.Rows[i];
            for (int j = 0; j < _dr.ItemArray.Length; j++)
            {
                //Debug.Log(dataTable.Rows[i][j].ToString());
                //將數據添加進列表
                clunmList.Add(dataTable.Rows[i][j].ToString());
            }
        }

        UserDoItemData vo_1 = null;
        UserDoItemData vo_2 = null;
        UserDoItemData vo_3 = null;
        //第一個學生類
        string[] okTextList = clunmList[1].Split('|');
        string[] okMsgList = clunmList[2].Split('|');
        for (int i = 0; i < okTextList.Length; i++)
        {
            vo_1 = new UserDoItemData(classId[0], okTextList[i], okMsgList[i]);
        }
        
        string[] okTextList1 = clunmList[5].Split('|');
        string[] okMsgList1 = clunmList[6].Split('|');
        for (int i = 0; i < okTextList1.Length; i++)
        {
            vo_2 = new UserDoItemData(classId[1], okTextList1[i], okMsgList1[i]);
        }
        
        string[] okTextList2 = clunmList[9].Split('|');
        string[] okMsgList2 = clunmList[10].Split('|');
        for (int i = 0; i < okTextList2.Length; i++)
        {
            vo_3 = new UserDoItemData(classId[2], okTextList2[i], okMsgList2[i]);
        }

        List<UserDoItemData> userItemList = new List<UserDoItemData>();
        userItemList.Add(vo_1);
        userItemList.Add(vo_2);
        userItemList.Add(vo_3);
        #endregion
    }

分享完了以後覺得有點心痛…
最後再分享一個方法吧(好人一生平安):

//取到Config下的配置文件
private string GetConfig(string name)
{
        classDrawConfig = Application.dataPath + "/Config/"+ name + ".txt";
        string configStr = File.ReadAllText(classDrawConfig);
        return configStr;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章