2D游戏案例:Unity答题系统(MySQL版)

Posted 代码骑士

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了2D游戏案例:Unity答题系统(MySQL版)相关的知识,希望对你有一定的参考价值。

目录

1、将准备好的题目存储在数据库中:

2、连接与查询

(1)建立连接与查询全部表数据代码: 

​(2)获取当前题目总数代码:

(3)插入新题目代码

         (4) 删除指定题目代码

(5)修改指定题目代码

(6)判断

         (7)排名


1、将准备好的题目存储在数据库中:

        可以使用爬虫,可以使用手动,这里先做个示例手动加几个。

(C#连接数据库方法在我之前的文章里:(4条消息) 使用Navicat连接MySQL的操作方法_代码骑士的博客-CSDN博客) 

2、连接与查询

先准备好插件:

 前三个:

后一个:

链接:https://pan.baidu.com/s/12_GISfD-kYUpQEwXDIL5cw 
提取码:caad 

(1)、建立连接与查询全部表数据代码: 

using mysql.Data.MySqlClient;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using UnityEngine;
using UnityEngine.UI;

public class SQLTEST : MonoBehaviour

    void Start()
    
        SQL_TEST();
    
     
    public void SQL_TEST()
    
        //建立连接语句
        string constr = "server=服务器IP地址;port=服务器端口;User Id=用户名;password=密码;Database=数据库名;charset=utf8";
        //建立连接
        MySqlConnection mycon = new MySqlConnection(constr);
        //打开连接
        mycon.Open();
        //查询数据
        string selstr = "select * from 表名";
        MySqlCommand cmd = new MySqlCommand(selstr, mycon);//参数1:查询语句,参数2:创建的连接
        MySqlDataReader reader = cmd.ExecuteReader();//读取游标
        string _num;
        string _quesiton;
        string _A;
        string _B;
        string _C;
        string _D;
        string _answer;

        List<string> s = new List<string>();

        while(reader.Read())
        
            _num = reader[0].ToString();//题号
            _quesiton = reader[1].ToString();//题目
            _A = reader[2].ToString();//A
            _B = reader[3].ToString();//B
            _C = reader[4].ToString();//C
            _D = reader[5].ToString();//D
            _answer = reader[6].ToString();//答案
            s.Add(_num);
            s.Add(_quesiton);
            s.Add(_A);
            s.Add(_B);
            s.Add(_C);
            s.Add(_D);
            s.Add(_answer);
        

        string texts="";

        mycon.Close();
        for (int i = 1; i < s.Count; i++)
        
            texts += s[i - 1];
            texts += '\\n';
        
        Debug.Log(texts);
    

输出样例:

(2)获取当前题目总数代码:

public void Que_Count()
    
        //建立连接语句
         string constr = "server=服务器公网网址;port=端口;User Id=用户名;password=密码;Database=数据库;charset=utf8";
        //建立连接
        MySqlConnection mycon = new MySqlConnection(constr);
        //打开连接
        mycon.Open();
        //查看当前的题目数量
        string selstr_1 = "select count(1) from quetest";
        //提交查询语句
        MySqlCommand cmd = new MySqlCommand(selstr_1, mycon);
        //设置游标
        MySqlDataReader reader = cmd.ExecuteReader();
        //读取数据
        string q_count ="";
        while(reader.Read())
        
            q_count = reader[0].ToString();
        
        //关闭连接
        mycon.Close();

        Debug.Log("当前的题目总数为:"+q_count);
    

输出结果: 

 (3)插入新题目代码


    public void INSERT_TEST()
    
        //输出总数
        Que_Count();

        //建立连接语句
        string constr = "server=服务器公网网址;port=端口;User Id=用户名;password=密码;Database=数据库;charset=utf8";
        //建立连接
        MySqlConnection mycon = new MySqlConnection(constr);
        //打开连接
        mycon.Open();

        Debug.Log("请输入新添的题号、题目、ACBD选项及答案:");
        /*
        Text q_num;
        Text q_que;
        Text q_A;
        Text q_B;
        Text q_C;
        Text q_D;
        Text q_ans;
        */
        //string _num = q_num.text;
        //string _que = q_que.text;
        //string _A = q_A.text;
        //string _B = q_B.text;
        //string _C = q_C.text;
        //string _D = q_D.text;
        //string _ans = q_ans.text;

        //测试用例,正常使用上面的从场景中获取输入
        string num = "6";
        string que = "1+1?";
        string A = "1";
        string B = "2";
        string C = "3";
        string D = "4";
        string ans = "2";
        //Debug.Log("题号:"+num+"题目:"+que+"ACBD选项:"+A+B+C+D+"答案:"+ans);
        string insertstr = "insert into quetest set number='"+ num + "',question='"+ que + "',A='"+ A + "',B='"+ B + "',C='"+ C + "',D='"+ D + "',Answer='"+ ans + "';";
        //提交查询语句
        MySqlCommand cmd = new MySqlCommand(insertstr, mycon);
        MySqlDataReader reader = cmd.ExecuteReader();
        while (reader.Read()) ;
        //关闭连接
        mycon.Close();
        //输出总数
        Que_Count();
    

 结果:

插入前:

插入后:

(4) 删除指定题目代码

        这里需要注意一点,删除操作是按题目编号删除的,因为是自己设置的题号没有让数据库自动编号,所以当删除的题不是最后一题时,原来的题号需要新的题来补充,如果发生题目序号乱序状态可以通过的表管理界面,右键排序(升序)即可恢复正常顺序。修改题目的方法也可以通过先删除和增加的方式实现或者用代码实现。

public void DELETE_TEST()
    
        //输出总数
        Que_Count();
        //建立连接语句
         string constr = "server=服务器公网网址;port=端口;User Id=用户名;password=密码;Database=数据库;charset=utf8";
        //建立连接
        MySqlConnection mycon = new MySqlConnection(constr);
        //打开连接
        mycon.Open();

        Debug.Log("请输入要删除的题号:");

        //Text num;
        string num;
        //测试用例
        
        num = "2";//删除题目2

        string deletestr = "delete from quetest where number='" + num + "'";
        MySqlCommand cmd = new MySqlCommand(deletestr, mycon);//申请
        MySqlDataReader reader = cmd.ExecuteReader();//提交
        while (reader.Read()) ;//执行
        //关闭连接
        mycon.Close();
        //输出总数
        Que_Count();
    

输出结果:

删除前:

删除后:

 

 (5)修改指定题目代码


    public void UPDATE_TEST()
    
        //UPDATE quetest set number = 7 WHERE number=1; 
        //建立连接语句
         string constr = "server=服务器公网网址;port=端口;User Id=用户名;password=密码;Database=数据库;charset=utf8";
        //建立连接
        MySqlConnection mycon = new MySqlConnection(constr);
        //打开连接
        mycon.Open();

        Debug.Log("请输入要删除的题号:");

        //Text num;
        string old_num;
        string new_num;

        //测试用例
        old_num = "7";
        new_num = "2";//修改题号7为题号2

        string updatestr = "update quetest set number = '"+new_num+"' WHERE number='"+old_num+"'";
        MySqlCommand cmd = new MySqlCommand(updatestr, mycon);//申请
        MySqlDataReader reader = cmd.ExecuteReader();//提交
        while (reader.Read()) ;//执行
        //关闭连接
        mycon.Close();
    

 修改前:

修改后:

 

 可以看到原本在最下面的7改为2后跳到了上面去,是因为设置了编号按升序排序。

(6)判断

        判断输入的题目的答案是否正确。

public void JUDGE_TEST()
    
        //以第4题为例

        //4 中国共产党成立的具体时间是( )。
        //A.1921年6月1号  B.1921年7月1号   C.1921年7月21号   D.1921年7月23号
        //答案:1921年7月23号(选D)

        //获取你的答案
        string num_ = "4";//获取题号
        string ans_ = "1921年7月1号";//B
         string constr = "server=服务器公网网址;port=端口;User Id=用户名;password=密码;Database=数据库;charset=utf8";
        //建立连接
        MySqlConnection mycon = new MySqlConnection(constr);
        //打开连接
        mycon.Open();
        //查看当前的题目数量
        string selstr = "select * from quetest where number = '"+num_+"'";
        //提交查询语句
        MySqlCommand cmd = new MySqlCommand(selstr, mycon);
        //设置游标
        MySqlDataReader reader = cmd.ExecuteReader();
        //读取数据
        bool flag = false;
        string qans = "";
        while (reader.Read())
        
            qans = reader[6].ToString();//获取题目答案
            if(qans == ans_)
            
                flag = true;
            
        
        //关闭连接
        mycon.Close();
        if(flag)
        
            Debug.Log("恭喜你,回答正确!");
        
        else
        
            Debug.Log("答案错误!正确答案是:"+qans);
        

    

结果:

答案不符:

答案正确: 

 

 (7)排名

最后我们再添加一个常用功能,新建一张表:得分表,将每次答完题后的分数进行存储,再按成绩大小进行排名最后实现排行榜,代码就放在这了,实现就是搭建场景的问题,由于时间原因我就先不在这里完整展示了。

public void RANK_TEST()
    
        string constr = "server=服务器公网网址;port=端口;User Id=用户名;password=密码;Database=数据库;charset=utf8";
        MySqlConnection mycon = new MySqlConnection(constr);
        mycon.Open();
        //读取数据
        string selstr = "select * from 表";
        MySqlCommand cmd = new MySqlCommand(selstr, mycon);
        MySqlDataReader reader = cmd.ExecuteReader();
        string temp1;
        string temp2;
        List<user> s = new List<user>();
        while (reader.Read())
        
            temp1 = reader[0].ToString();//用户名
            temp2 = reader[2].ToString();//得分
            s.Add(new user(temp1, int.Parse(temp2)));
        
        s.Sort((x, y) =>  return -x.score.CompareTo(y.score); );//升序排序
        texts = " ";
        for (int i = 0; i < s.Count; i++)
        
            texts += ((i + 1).ToString() + "\\t用户名: " + s[i].username + "\\t" + " 总得分: " + s[i].score + " 分").ToString();
            texts += '\\n';
            texts += '\\n';
        
        userName_And_userScore.text = texts;
        mycon.Close();
    
    public class user
    
        public string username;
        public int score;
        public user(string username, int score)
        
            this.username = username;
            this.score = score;
        
    

2D游戏案例:Unity答题系统(TXT+界面版)

目录

一、作品展示

1、菜单界面:

2、答题界面:

3、学习模式界面:

二、代码展示:

1、菜单页面:

        三个场景跳转按钮:

        (1)学习党史按钮: 

        (2)答题测试按钮:

        (3)退出系统按钮:

  

 2、退出按钮:

5、学习界面代码:

(1)代码

4、答题界面代码:

(1)返回开始菜单按钮:

(2)答题处理主代码:

三、相应资源:

1、txt文件格式

 2、如何修改题目内容

四、尾声





一、作品展示

1、菜单界面:

 (注:由于特殊原因,原图无法展示,请谅解)

2、答题界面:

  (注:由于特殊原因,原图无法展示,请谅解)

3、学习模式界面:

  (注:由于特殊原因,原图无法展示,请谅解)

二、代码展示:

1、菜单页面:

        三个场景跳转按钮:

        (1)学习党史按钮: 

using UnityEngine.SceneManagement;
using UnityEngine;

public class EnterStudy : MonoBehaviour

    public void EnterStudy_()
    
        SceneManager.LoadScene("学习界面");
    

        (2)答题测试按钮:

using UnityEngine.SceneManagement;
using UnityEngine;

public class EnterTest : MonoBehaviour

    public void EnterTest_()
    
        SceneManager.LoadScene("example");
    

        (3)退出系统按钮:

using UnityEngine;

public class ExitSystem : MonoBehaviour

    public void Quit()
    
        Application.Quit();
    

  

 2、退出按钮:

using UnityEngine;

public class ExitSystem : MonoBehaviour

    public void Quit()
    
        Application.Quit();
    

5、学习界面代码:

(1)代码

using UnityEngine;
using UnityEngine.UI;
using System.IO;
using System.Text;
using System.Collections.Generic;

public class TXT_OPRATION : MonoBehaviour

    //public TextAsset textTxt;
    //读取文档
    string[][] ArrayX;//题目数据
    string[] lineArray;//读取到题目数据

    public Text stuText;
    string[] items = new string[7]"题号:", "题目:", "A:", "B:", "C:", "D:", "答案:" ;

    void Start()
    
        LoadTxt();
        //Debug.Log(textTxt.text);
    

    private void LoadTxt()
    
        string UnityPath1 = Application.dataPath + "/StreamingAssets/题目5.txt";
        string[] allLineText = File.ReadAllLines(UnityPath1);
        for (int i = 0; i < allLineText.Length; i++)
        
            Debug.Log(allLineText.Length);
        
        ArrayX = new string[allLineText.Length][];
        //把csv中的数据储存在二维数组中  
        for (int i = 0; i < allLineText.Length; i++)
        
            ArrayX[i] = allLineText[i].Split(':');
        
        //查看保存的题目数据
        int k = 0;
        string texts = "";
        for (int i = 0; i < ArrayX.Length; i++)
        
            //texts += "题号:";
            for (int j = 0; j < ArrayX[i].Length; j++)
            
                //Debug.Log(ArrayX[i][j]);
                texts += items[k];
                texts += ArrayX[i][j];
                texts += '\\n';
                k++;
                if (k == 7)
                
                    k = 0;
                
            
        

        stuText.text = texts;

    

4、答题界面代码:

(1)返回开始菜单按钮:

using UnityEngine.SceneManagement;
using UnityEngine;

public class returnMenu : MonoBehaviour

    public void ReturnMenu()
    
        SceneManager.LoadScene("登录界面");
    

(2)答题处理主代码:

using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using System.IO;
using System.Text;

public class testAnswer : MonoBehaviour
 
    //读取文档
    string[][] ArrayX;//题目数据
    string[] lineArray;//读取到题目数据
    private int topicMax = 0;//最大题数
    private List<bool> isAnserList = new List<bool>();//存放是否答过题的状态

    //加载题目
    public GameObject tipsbtn;//提示按钮
    public Text tipsText;//提示信息
    public List<Toggle> toggleList;//答题Toggle
    public Text indexText;//当前第几题
    public Text TM_Text;//当前题目
    public List<Text> DA_TextList;//选项
    private int topicIndex = 0;//第几题

    //按钮功能及提示信息
    public Button BtnBack;//上一题
    public Button BtnNext;//下一题
    public Button BtnTip;//消息提醒
    public Button BtnJump;//跳转题目
    public InputField jumpInput;//跳转题目
    public Text TextAccuracy;//正确率
    private int anserint = 0;//已经答过几题
    private int isRightNum = 0;//正确题数

    void Awake()
    
        TextCsv();
        LoadAnswer();
    

    void Start()
    
        toggleList[0].onValueChanged.AddListener((isOn) => AnswerRightRrongJudgment(isOn, 0));
        toggleList[1].onValueChanged.AddListener((isOn) => AnswerRightRrongJudgment(isOn, 1));
        toggleList[2].onValueChanged.AddListener((isOn) => AnswerRightRrongJudgment(isOn, 2));
        toggleList[3].onValueChanged.AddListener((isOn) => AnswerRightRrongJudgment(isOn, 3));

        BtnTip.onClick.AddListener(() => Select_Answer(0));
        BtnBack.onClick.AddListener(() => Select_Answer(1));
        BtnNext.onClick.AddListener(() => Select_Answer(2));
        BtnJump.onClick.AddListener(() => Select_Answer(3));
    


    /*****************读取txt数据******************/
    void TextCsv()
    
        string UnityPath1 = Application.dataPath + "/StreamingAssets/题目5.txt";
        string[] allLineText = File.ReadAllLines(UnityPath1);
        for (int i = 0; i < allLineText.Length; i++)
        
            Debug.Log(allLineText.Length);
        
        ArrayX = new string[allLineText.Length][];
        //把csv中的数据储存在二维数组中  
        for (int i = 0; i < allLineText.Length; i++)
        
            ArrayX[i] = allLineText[i].Split(':');
        
        /*
        //查看保存的题目数据
        for (int i = 0; i < ArrayX.Length; i++)
        
            for (int j = 0; j < ArrayX[i].Length; j++)
            
                Debug.Log(ArrayX[i][j]);
            
        
        */
        //设置题目状态
        topicMax = allLineText.Length;
        for (int x = 0; x < topicMax; x++)
        
            isAnserList.Add(false);
        
    

    /*****************加载题目******************/
    void LoadAnswer()
    
        for (int i = 0; i < toggleList.Count; i++)
        
            toggleList[i].isOn = false;
        
        for (int i = 0; i < toggleList.Count; i++)
        
            toggleList[i].interactable = true;
        

        tipsbtn.SetActive(false);
        tipsText.text = "";

        indexText.text = "第" + (topicIndex + 1) + "题:";//第几题
        TM_Text.text = ArrayX[topicIndex][1];//题目
        int idx = ArrayX[topicIndex].Length - 3;//有几个选项
        for (int x = 0; x < idx; x++)
        
            DA_TextList[x].text = ArrayX[topicIndex][x + 2];//选项
        
    

    /*****************按钮功能******************/
    void Select_Answer(int index)
    
        switch (index)
        
            case 0://提示
                int idx = ArrayX[topicIndex].Length - 1;
                int n = int.Parse(ArrayX[topicIndex][idx]);
                string nM = "";
                switch (n)
                
                    case 1:
                        nM = "A";
                        break;
                    case 2:
                        nM = "B";
                        break;
                    case 3:
                        nM = "C";
                        break;
                    case 4:
                        nM = "D";
                        break;
                
                tipsText.text = "<color=#FFAB08FF>" + "正确答案是:" + nM + "</color>";
                break;
            case 1://上一题
                if (topicIndex > 0)
                
                    topicIndex--;
                    LoadAnswer();
                
                else
                
                    tipsText.text = "<color=#27FF02FF>" + "前面已经没有题目了!" + "</color>";
                
                break;
            case 2://下一题
                if (topicIndex < topicMax - 1)
                
                    topicIndex++;
                    LoadAnswer();
                
                else
                
                    tipsText.text = "<color=#27FF02FF>" + "哎呀!已经是最后一题了。" + "</color>";
                
                break;
            case 3://跳转
                int x = int.Parse(jumpInput.text) - 1;
                if (x >= 0 && x < topicMax)
                
                    topicIndex = x;
                    jumpInput.text = "";
                    LoadAnswer();
                
                else
                
                    tipsText.text = "<color=#27FF02FF>" + "不在范围内!" + "</color>";
                
                break;
        
    

    /*****************题目对错判断******************/
    void AnswerRightRrongJudgment(bool check, int index)
    
        if (check)
        
            //判断题目对错
            bool isRight;
            int idx = ArrayX[topicIndex].Length - 1;
            int n = int.Parse(ArrayX[topicIndex][idx]) - 1;
            if (n == index)
            
                tipsText.text = "<color=#27FF02FF>" + "恭喜你,答对了!" + "</color>";
                isRight = true;
                tipsbtn.SetActive(true);
            
            else
            
                tipsText.text = "<color=#FF0020FF>" + "对不起,答错了!" + "</color>";
                isRight = false;
                tipsbtn.SetActive(true);
            

            //正确率计算
            if (isAnserList[topicIndex])
            
                tipsText.text = "<color=#FF0020FF>" + "这道题已答过!" + "</color>";
            
            else
            
                anserint++;
                if (isRight)
                
                    isRightNum++;
                
                isAnserList[topicIndex] = true;
                TextAccuracy.text = "正确率:" + ((float)isRightNum / anserint * 100).ToString("f2") + "%";
            

            //禁用掉选项
            for (int i = 0; i < toggleList.Count; i++)
            
                toggleList[i].interactable = false;
            
        
    

三、相应资源:

1、txt文件格式

题号:题目:A选项:B选项:C选项:D选项:答案的序号
题号:题目:A选项:B选项:C选项:D选项:答案的序号
题号:题目:A选项:B选项:C选项:D选项:答案的序号
题号:题目:A选项:B选项:C选项:D选项:答案的序号
题号:题目:A选项:B选项:C选项:D选项:答案的序号
……
(注:最后一题的末尾不加回车,所有冒号都是英文格式)

 2、如何修改题目内容

        这是本系统的一大亮点,也是Unity开发的一个神奇的特性。往往我们做的程序想要修改信息都要连接云服务器、数据库什么的,很少有能在本地直接修改的,并且修改完内置文件之后往往都会使程序崩溃,本系统使用的数据修改方法是将题目写在外部文档,使程序能够动态读取和修改题目信息。这种方式支持的文档格式可以是txt、xml、json,本系统用的是最简便的txt文本。

        这是因为我们在Unity中新建一个StreamingAssets文件夹,这个文件夹中的内容可以在应用发布时原封不动地打包进去(不会被加密和压缩),一般用来存放二进制文件。

        有了这个文件夹,我们就可以在打包完之后也可以进行文件中的修改(只限制于StreamingAssets文件夹)从而实现增删题目的功能。

        唯一的限制就是添加修改题目要满足固定格式,不然读取会出现错误。

 (按此路径找到题目文件)

E:\\xx学习系统5.0plus\\xx学习与答题系统_Data\\StreamingAssets

四、尾声

 诚挚感谢博主恬静的小魔龙 、

York_New和的文章令我受益匪浅。

参考文章:(8条消息) 【Unity3D应用案例系列】答题系统开发_恬静的小魔龙的博客-CSDN博客_unity答题系统https://blog.csdn.net/q764424567/article/details/117259582?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522165191697316781483767112%2522%252C%2522scm%2522%253A%252220140713.130102334..%2522%257D&request_id=165191697316781483767112&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~top_click~default-1-117259582-null-null.142%5Ev9%5Epc_search_result_control_group,157%5Ev4%5Econtrol&utm_term=unity%E7%AD%94%E9%A2%98&spm=1018.2226.3001.4187

(2条消息) Unity学习篇之txt文本文档的多种读写方式_York_New的博客-CSDN博客_unity读取文本https://blog.csdn.net/York_New/article/details/84302895?utm_medium=distribute.pc_aggpage_search_result.none-task-blog-2~aggregatepage~first_rank_ecpm_v1~rank_v31_ecpm-1-84302895-null-null.pc_agg_new_rank&utm_term=unity%E4%BF%AE%E6%94%B9txt&spm=1000.2123.3001.4430(4条消息) Unity学习篇之txt文本文档的多种读写方式_York_New的博客-CSDN博客_unity读取文本https://blog.csdn.net/York_New/article/details/84302895?utm_medium=distribute.pc_aggpage_search_result.none-task-blog-2~aggregatepage~first_rank_ecpm_v1~rank_v31_ecpm-1-84302895-null-null.pc_agg_new_rank&utm_term=unity%E4%BF%AE%E6%94%B9txt&spm=1000.2123.3001.4430

(2条消息) unity修改txt - CSDNhttps://www.csdn.net/tags/Mtjacg5sMTI3NjEtYmxvZwO0O0OO0O0O.html

最后放上作品链接,大家一起来学习吧!

链接:https://pan.baidu.com/s/1Em67E803tY_HHyEcg7tgCw 
提取码:uf29

工程文件资源获取:

unity游戏案例:知识学习系统-Unity3D文档类资源-CSDN下载

以上是关于2D游戏案例:Unity答题系统(MySQL版)的主要内容,如果未能解决你的问题,请参考以下文章

小白可以用unity 制作2D 横版游戏吗?

Unity3D应用案例系列答题系统开发

Unity3D应用案例系列答题系统开发

Unity2D横版游戏地形生成

unity2D横版游戏教程5-UI

unity2D横版游戏教程-1 让人物动起来