You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

988 lines
30 KiB

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.UI;
using Random = UnityEngine.Random;
public class GameRoot : MonoBehaviour
{
public static GameRoot Instance = null;
private float _score = 0;
private ResSvc resSvc;
[Header("是否随机加载关卡")]
public bool isRndom = false;
//记录关卡是否完成
[HideInInspector]
public bool[] PassOverGroup;
private int AllPassCount;
public Transform PassPreant;
public GameObject _cavans;
[Header("组件")]
public Button TimeOutBtn;
public GameObject TimeOutTip;
public GameObject SlectedWnd;
public GameObject ResultWnd;
public GameObject sumbitTip;
public Text relustTxt;
public Text testTxt;
public Text scoreTxt;
public Text titleTxt;
[Header("倒计时组件")]
public bool isCountDown = false;
public GameObject TimeObj;
public Text minuteTxt;
public Text secondTxt;
[Header("当前正在答题关卡")]
public PassPart CurrentPass;
//记录选择题答案字典
public Dictionary<int, Dictionary<int, int>> _choiceDict = new Dictionary<int, Dictionary<int, int>>();
//记录多选题答案字典
public Dictionary<int, Dictionary<int, int[]>> _moreChoiceDict = new Dictionary<int, Dictionary<int, int[]>>();
//记录操作题答案字典
public Dictionary<int, Dictionary<int, bool[]>> _oprerationDict = new Dictionary<int, Dictionary<int, bool[]>>();
//关卡管理
[HideInInspector]
public List<PassPart> _passList = new List<PassPart>();
//错题集合
public Dictionary<int, List<int>> _errorDict = new Dictionary<int, List<int>>();
public List<int> _unDoneList = new List<int>();
//已检查过的多答案题
private Dictionary<int, int> OKQuesitionDict = new Dictionary<int, int>();
private void Awake()
{
if (GameRoot.Instance == null)
{
DontDestroyOnLoad(this);
Instance = this;
}
//配置文件加载
resSvc = GetComponent<ResSvc>();
resSvc.Init();
//关卡完成状态初始化
if (isRndom)
{
AllPassCount = 20;
}
else
{
AllPassCount = 32;
}
PassOverGroup = new bool[AllPassCount + 1];
for (int i = 0; i < PassOverGroup.Length; i++)
{
PassOverGroup[i] = false;
}
//加载菜单
LoadMenu();
//_cavans = this.transform.Find("Canvas").gameObject;
testTxt.text = Screen.width + "-" + Screen.height;
TimeOutBtn.onClick.AddListener(() =>
{
TimeOutTip.SetActive(false);
TimeObj.SetActive(false);
//CheckAllPassOver();
//ChceckAllAnswer();
ReturnMenu();
});
if (isRndom)
{
titleTxt.text = "消防技能在线模拟考试-考核模式";
}
else
{
titleTxt.text = "消防技能在线模拟考试-练习模式";
}
}
private void Update()
{
if (prgCB != null)
{
prgCB();
}
//更新得分
_score = Mathf.Clamp(_score, 0, 100);
scoreTxt.text = _score.ToString();
}
/// <summary>
/// 提交按钮的所有题是否完成检测方法
/// </summary>
public void CheckAllPassOver()
{
int num = 0;
for (int i = 0; i < PassOverGroup.Length; i++)
{
if (PassOverGroup[i])
{
num++;
}
}
if (num != PassOverGroup.Length)
{
sumbitTip.gameObject.SetActive(true);
}
else
{
Result();
}
}
#region 答案管理方法
/// <summary>
/// 检查所有题型答案
/// </summary>
public void ChceckAllAnswer()
{
CheckChoiceAnswer();
CheckMoreChoiceAnswer();
CheckOperationAnswer();
string str = "";
foreach (var item in _errorDict)
{
str += "-" + item.Key;
}
Debug.Log("错题有:" + str);
}
/// <summary>
/// 提交选择题答案函数
/// PassIndex:关卡索引
/// QuestionIndex:问题索引
/// answer:记录用户所选的答案(ABCD对应0123)
/// </summary>
/// <param name="PassIndex">关卡索引</param>
/// <param name="QuestionIndex">问题索引</param>
/// <param name="answer">记录用户所选的答案(ABCD对应0123)</param>
public static void SubmitChoiceAnswer(int PassIndex, int QuestionIndex, int answer)
{
Debug.Log("记录第" + PassIndex + "关卡" + QuestionIndex + "的问题答案为" + answer);
if (GameRoot.Instance == null) return;
//如果不存在则创建并放入字典
if (!GameRoot.Instance._choiceDict.ContainsKey(PassIndex))
{
Dictionary<int, int> dict = new Dictionary<int, int>();
dict.Add(QuestionIndex, answer);
GameRoot.Instance._choiceDict.Add(PassIndex, dict);
Debug.Log("记录第" + PassIndex + "关卡" + QuestionIndex + "的问题答案为" + answer);
}
else
{
//继续记录
int data = answer;
Dictionary<int, int> dict = new Dictionary<int, int>();
if (GameRoot.Instance._choiceDict.TryGetValue(PassIndex, out dict))
{
dict[QuestionIndex] = data;
GameRoot.Instance._choiceDict[PassIndex] = dict;
Debug.Log("关卡字典已存在,更新" + QuestionIndex + "问题的答案为" + answer);
}
}
}
/// <summary>
/// 提交多选题答案函数
/// PassIndex:关卡索引
/// QuestionIndex:问题索引
/// answer:记录用户所选的答案(ABCD对应0123)
/// </summary>
/// <param name="PassIndex">关卡索引</param>
/// <param name="QuestionIndex">问题索引</param>
/// <param name="answer">记录用户所选的答案</param>
public static void SubmitMoreChoiceAnswer(int PassIndex, int QuestionIndex, int[] answer)
{
Debug.Log("测试" + "记录第" + PassIndex + "关卡" + QuestionIndex + "的问题答案为" + ArrToString(answer));
if (GameRoot.Instance == null) return;
//如果不存在则创建并放入字典
if (!GameRoot.Instance._moreChoiceDict.ContainsKey(PassIndex))
{
Dictionary<int, int[]> dict = new Dictionary<int, int[]>();
dict.Add(QuestionIndex, answer);
GameRoot.Instance._moreChoiceDict.Add(PassIndex, dict);
Debug.Log("记录第" + PassIndex + "关卡" + QuestionIndex + "的问题答案为" + ArrToString(answer));
}
else
{
//继续记录
int[] data = answer;
Dictionary<int, int[]> dict = new Dictionary<int, int[]>();
if (GameRoot.Instance._moreChoiceDict.TryGetValue(PassIndex, out dict))
{
dict[QuestionIndex] = data;
GameRoot.Instance._moreChoiceDict[PassIndex] = dict;
Debug.Log("关卡字典已存在,更新" + QuestionIndex + "问题的答案为" + answer);
}
}
}
/// <summary>
/// 提交操作题答案函数
/// PassIndex:关卡索引
/// QuestionIndex:问题索引
/// answer:记录用户所选的答案(ABCD对应0123)
/// </summary>
/// <param name="PassIndex">关卡索引</param>
/// <param name="QuestionIndex">问题索引</param>
/// <param name="answer">记录用户所选的答案</param>
public static void SubmitOprerationAnswer(int PassIndex, int QuestionIndex, bool[] answer)
{
Debug.Log("测试" + "记录第" + PassIndex + "关卡" + QuestionIndex + "的问题答案为" + answer);
if (GameRoot.Instance == null) return;
//如果不存在则创建并放入字典
if (!GameRoot.Instance._oprerationDict.ContainsKey(PassIndex))
{
Dictionary<int, bool[]> dict = new Dictionary<int, bool[]>();
dict.Add(QuestionIndex, answer);
GameRoot.Instance._oprerationDict.Add(PassIndex, dict);
Debug.Log("记录第" + PassIndex + "关卡" + QuestionIndex + "的问题答案为" + answer);
}
else
{
//继续记录
bool[] data = answer;
Dictionary<int, bool[]> dict = new Dictionary<int, bool[]>();
if (GameRoot.Instance._oprerationDict.TryGetValue(PassIndex, out dict))
{
dict[QuestionIndex] = data;
GameRoot.Instance._oprerationDict[PassIndex] = dict;
Debug.Log("关卡字典已存在,更新" + QuestionIndex + "问题的答案为" + answer);
}
}
}
/// <summary>
/// 核算选择题方法
/// </summary>
public void CheckChoiceAnswer()
{
foreach (var item in _choiceDict)
{
PassPart passPart = null;
int PassIndex = item.Key;
List<int> list = new List<int>();
foreach (var answer in item.Value)
{
switch (PassIndex)
{
case 1:
if (answer.Key == 7)
{
if (answer.Value == 1 || answer.Value == 4)
{
_score += resSvc.GetQuestionScore(PassIndex, answer.Key);
}
else
{
#region 加入错误集
for (int i = 0; i < _passList.Count; i++)
{
if (_passList[i].passInfo.PassIndex == PassIndex)
{
passPart = _passList[i];
}
}
list.Add(answer.Key);
if (_errorDict.ContainsKey(passPart._passIndex))
{
List<int> templist = new List<int>();
templist = _errorDict[passPart._passIndex];
if (!templist.Contains(answer.Key))
{
templist.Add(answer.Key);
}
_errorDict[passPart._passIndex] = templist;
}
else
{
_errorDict.Add(passPart._passIndex, list);
}
Debug.Log("第" + passPart._passIndex + "关第" + answer.Key + "小题错误");
#endregion
}
OKQuesitionDict.Add(1, 7);
}
break;
case 7:
if (answer.Key == 1)
{
if (answer.Value == 1 || answer.Value == 2)
{
_score += resSvc.GetQuestionScore(PassIndex, answer.Key);
}
else
{
#region 加入错误集
for (int i = 0; i < _passList.Count; i++)
{
if (_passList[i].passInfo.PassIndex == PassIndex)
{
passPart = _passList[i];
}
}
list.Add(answer.Key);
if (_errorDict.ContainsKey(passPart._passIndex))
{
List<int> templist = new List<int>();
templist = _errorDict[passPart._passIndex];
if (!templist.Contains(answer.Key))
{
templist.Add(answer.Key);
}
_errorDict[passPart._passIndex] = templist;
}
else
{
_errorDict.Add(passPart._passIndex, list);
}
Debug.Log("第" + passPart._passIndex + "关第" + answer.Key + "小题错误");
#endregion
}
OKQuesitionDict.Add(7, 1);
}
if (answer.Key == 3)
{
_score += resSvc.GetQuestionScore(PassIndex, answer.Key);
OKQuesitionDict.Add(7, 3);
}
break;
}
//此变量用来判断当前小题是否是已经判断过的“多答案题”,如是则跳往下个小题判断
bool skip = false;
foreach (var value in OKQuesitionDict)
{
if (PassIndex == value.Key && value.Value == answer.Key)
{
skip = true;
}
}
if (!skip)
{
if (resSvc.CheckAnswerIsTrue(PassIndex, answer.Key, answer.Value) == false)//如果错误则加入错题集
{
for (int i = 0; i < _passList.Count; i++)
{
if (_passList[i].passInfo.PassIndex == PassIndex)
{
passPart = _passList[i];
}
}
list.Add(answer.Key);
if (_errorDict.ContainsKey(passPart._passIndex))
{
List<int> templist = new List<int>();
templist = _errorDict[passPart._passIndex];
if (!templist.Contains(answer.Key))
{
templist.Add(answer.Key);
}
_errorDict[passPart._passIndex] = templist;
}
else
{
_errorDict.Add(passPart._passIndex, list);
}
Debug.Log("第" + passPart._passIndex + "关第" + answer.Key + "小题错误");
}
else
{
_score += resSvc.GetQuestionScore(PassIndex, answer.Key);
}
}
}
}
}
/// <summary>
/// 核算多选题题方法
/// </summary>
public void CheckMoreChoiceAnswer()
{
foreach (var item in _moreChoiceDict)
{
PassPart passPart = null;
int PassIndex = item.Key;
List<int> list = new List<int>();
foreach (var answer in item.Value)
{
if (resSvc.CheckAnswerIsTrue(PassIndex, answer.Key, answer.Value) == false)//如果错误则加入错题集
{
for (int i = 0; i < _passList.Count; i++)
{
if (_passList[i].passInfo.PassIndex == PassIndex)
{
passPart = _passList[i];
}
}
list.Add(answer.Key);
if (_errorDict.ContainsKey(passPart._passIndex))
{
List<int> templist = new List<int>();
templist = _errorDict[passPart._passIndex];
if (!templist.Contains(answer.Key))
{
templist.Add(answer.Key);
}
_errorDict[passPart._passIndex] = templist;
}
else
{
_errorDict.Add(passPart._passIndex, list);
}
Debug.Log("第" + passPart._passIndex + "关第" + answer.Key + "小题错误");
}
else
{
_score += resSvc.GetQuestionScore(PassIndex, answer.Key);
}
}
}
}
/// <summary>
/// 核算操作题方法
/// </summary>
public void CheckOperationAnswer()
{
foreach (var item in _oprerationDict)
{
PassPart passPart = null;
int PassIndex = item.Key;
List<int> list = new List<int>();
foreach (var answer in item.Value)
{
for (int i = 0; i < answer.Value.Length; i++)
{
if (answer.Value[i] == false)
{
for (int j = 0; j < _passList.Count; j++)
{
if (_passList[j].passInfo.PassIndex == PassIndex)
{
passPart = _passList[j];
}
}
list.Add(answer.Key);
if (_errorDict.ContainsKey(passPart._passIndex))
{
List<int> templist = new List<int>();
templist = _errorDict[passPart._passIndex];
if (!templist.Contains(answer.Key))
{
templist.Add(answer.Key);
}
_errorDict[passPart._passIndex] = templist;
}
else
{
_errorDict.Add(passPart._passIndex, list);
}
Debug.Log("第" + passPart._passIndex + "关第" + answer.Key + "小题错误");
}
else
{
_score += resSvc.GetQuestionScore(PassIndex, answer.Key);
}
}
}
}
}
#endregion
#region 关卡管理
/// <summary>
/// 考核模式下计时
/// </summary>
public void StartCountDownTime()
{
isCountDown = true;
TimeObj.SetActive(true);
float time = CurrentPass.passInfo.time;
StartCoroutine(CountDown(time, minuteTxt, secondTxt, () =>
{
// PassOverGroup[CurrentPass._passIndex] = true;
CurrentPass.passOver();
TimeOutTip.SetActive(true);
}));
}
IEnumerator CountDown(float minute, Text MinuteText, Text SecendText, Action action = null)
{
float min = minute;
float scend = 0;
MinuteText.text = min.ToString("0");
SecendText.text = scend.ToString("0");
while (isCountDown)
{
yield return new WaitForEndOfFrame();
if (scend <= 0)
{
min -= 1;
scend = 60;
MinuteText.text = min.ToString("0");
SecendText.text = scend.ToString("0");
}
else
{
scend -= Time.deltaTime;
SecendText.text = scend.ToString("0");
}
if (min < 0)
{
MinuteText.text = 0.ToString("0");
SecendText.text = 0.ToString("0");
if (action != null) action();
break;
}
}
}
/// <summary>
/// 加载关卡选择窗口
/// </summary>
/// <param name="path"></param>
/// <param name="isRandom"></param>
/// <param name="passNum"></param>
/// <param name="parent"></param>
public void LoadPassPart(string path, bool isRandom, int passNum, Transform parent)
{
if (!isRandom)
{
if (_passList.Count == 0)
{
for (int i = 1; i < passNum + 1; i++)
{
GameObject pass = Resources.Load<GameObject>(path);
if (pass != null)
{
int index = i;
PassInfo info = resSvc.GetPassInfo(i);
if (info != null)
{
GameObject go = GameObject.Instantiate(pass, parent);
PassPart passPart = go.AddComponent<PassPart>();
passPart.passInfo = info;
passPart.SetPassIndex(index);
passPart.Init();
//记录
_passList.Add(passPart);
}
else
{
Debug.Log("加载" + info + "不存在");
}
}
else
{
Debug.Log(path + "加载预设不存在");
}
}
}
}
else
{
if (_passList.Count == 0)
{
//先生成必考的八个
for (int i = 1; i <= 8; i++)
{
GameObject pass = Resources.Load<GameObject>(path);
if (pass != null)
{
int index = i;
PassInfo info = resSvc.GetPassInfo(i);
if (info != null)
{
GameObject go = GameObject.Instantiate(pass, parent);
PassPart passPart = go.AddComponent<PassPart>();
passPart.passInfo = info;
passPart.SetPassIndex(index);
passPart.Init();
//记录
_passList.Add(passPart);
}
else
{
Debug.Log("加载" + info + "不存在");
}
}
}
int[] nums = new int[24];
for (int i = 0; i < 24; i++)
{
nums[i] = i + 9;
}
//GetRandomNum(nums);
RandomSort(nums);
for (int i = 0; i < 12; i++)
{
GameObject pass = Resources.Load<GameObject>(path);
if (pass != null)
{
int index = nums[i];
PassInfo info = resSvc.GetPassInfo(index);
if (info != null)
{
GameObject go = GameObject.Instantiate(pass, parent);
PassPart passPart = go.AddComponent<PassPart>();
passPart.passInfo = info;
passPart.SetPassIndex(i + 9);
passPart.Init();
//记录
_passList.Add(passPart);
}
else
{
Debug.Log("加载" + info + "不存在");
}
}
}
}
}
}
/// <summary>
/// 记录关卡是否完成
/// </summary>
/// <param name="passIndex">关卡索引</param>
/// <param name="isover">是否完成</param>
public static void SubmitPassState(int passIndex, bool isover)
{
if (GameRoot.Instance == null || isover == false) return;
foreach (var item in GameRoot.Instance._passList)
{
if (item.passInfo.PassIndex == passIndex)
{
GameRoot.Instance.PassOverGroup[item._passIndex] = true;
Debug.Log("提示:" + item._passIndex + "关已完成");
}
}
}
private Action prgCB = null;
public void AsyncLoadScene(string sceneName, Action loaded)
{
AsyncOperation sceneAsync = SceneManager.LoadSceneAsync(sceneName);
prgCB = () =>
{
float val = sceneAsync.progress;
if (val == 1)
{
if (loaded != null)
{
loaded();
}
prgCB = null;
sceneAsync = null;
}
};
}
public void LoadMenu()
{
if (GameRoot.Instance == null) return;
AsyncLoadScene("Menu", () =>
{
//关卡窗口加载
LoadPassPart("Prefab/UI/part", isRndom, AllPassCount, PassPreant);
_cavans.SetActive(true);
});
}
/// <summary>
/// 返回大厅方法
/// </summary>
public static void ReturnMenu()
{
if (GameRoot.Instance != null)
{
//异步加载并且检测已完成的关卡
GameRoot.Instance.AsyncLoadScene("Menu", () =>
{
int num = GameRoot.Instance.PassOverGroup.Length;
int overNum = 0;
for (int i = 1; i < num; i++)
{
if (GameRoot.Instance.PassOverGroup[i] == true)
{
foreach (var item in GameRoot.Instance._passList)
{
if (item._passIndex == i)
{
overNum += 1;
item.passOver();
}
}
}
}
if (overNum == GameRoot.Instance.AllPassCount)
{
//跳转进结算界面
Debug.Log("所有关卡已完成");
GameRoot.Instance.Result();
}
Debug.Log("目前已完成的关卡数:" + overNum);
//关卡窗口恢复
GameRoot.Instance.SetActiveMenuCanvans(true);
if (GameRoot.Instance.isRndom)
{
GameRoot.Instance.TimeObj.SetActive(false);
GameRoot.Instance.isCountDown = false;
}
});
}
else
{
SceneManager.LoadScene("Menu");
}
}
public void SetActiveMenuCanvans(bool b)
{
_cavans.SetActive(b);
}
/// <summary>
/// 答题结果
/// </summary>
public void Result()
{
SlectedWnd.SetActive(false);
ResultWnd.SetActive(true);
//检查未做的题
for (int i = 1; i < AllPassCount; i++)
{
if (PassOverGroup[i] == false)
{
_unDoneList.Add(i);
}
}
GameObject errtip = Resources.Load<GameObject>("Prefab/UI/errorTip");
GameObject emptyTip = Resources.Load<GameObject>("Prefab/UI/empytTip");
Transform preant = GameObject.FindGameObjectWithTag("ErrorTipPreant").transform;
//显示错题提示
int num = 0;
if (errtip != null && emptyTip != null)
{
foreach (var item in _errorDict)
{
for (int i = 0; i < item.Value.Count; i++)
{
GameObject go = GameObject.Instantiate(errtip, preant);
go.transform.GetChild(0).GetComponent<Text>().text = item.Key + "-" + item.Value[i];
num++;
}
}
for (int i = 0; i < _unDoneList.Count; i++)
{
GameObject go = GameObject.Instantiate(emptyTip, preant);
go.transform.GetChild(0).GetComponent<Text>().text = _unDoneList[i].ToString();
num++;
}
relustTxt.text = num.ToString();
}
}
//重新开启答题
public void ReStart()
{
Destroy(this.gameObject);
SceneManager.LoadScene("Start");
//ResultWnd.SetActive(false);
//SlectedWnd.SetActive(true);
}
#endregion
#region 其他
void RandomSort(int[] array)
{
int last = array.Length - 1;
for (int i = 0; i < array.Length; i++)
{
//剩下的牌的总数
int num = array.Length - i;
int randomIndex = Random.Range(0, num);//随机抽一张牌
int temp = array[last];
array[last] = array[randomIndex];
array[randomIndex] = temp;
last--;//位置改变
}
}
public int[] GetRandomNum(int[] num)
{
for (int i = 0; i < num.Length; i++)
{
int temp = num[i];
int randomIndex = Random.Range(0, num.Length);
num[i] = num[randomIndex];
num[randomIndex] = temp;
}
return num;
}
public static string ArrToString(int[] arr)
{
string str = "";
int[] arrP = Sort(arr);
for (int i = 0; i < arrP.Length; i++)
{
if (arrP[i].ToString() != "")
{
str += arrP[i].ToString();
}
}
return str;
}
public static string ArrToString(bool[] arr)
{
string str = "";
for (int i = 0; i < arr.Length; i++)
{
if (arr[i].ToString() != "")
{
str += arr[i].ToString();
}
}
return str;
}
public static int[] Sort(int[] arr)
{
for (var i = 0; i < arr.Length; i++)
{
//每一轮数值比较
for (var j = i; j < arr.Length - 1; j++)
{
//谁小谁放在前面
if (arr[i] > arr[i + 1])
{
var temp = arr[i];
arr[i] = arr[i + 1];
arr[i + 1] = temp;
}
}
}
return arr;
#endregion
}
}