GeneratingTarget.cs 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686
  1. using System.Collections;
  2. using System.Collections.Generic;
  3. using TMPro;
  4. using UnityEngine;
  5. using UnityEngine.EventSystems;
  6. using UnityEngine.UI;
  7. using UnityEngine.SceneManagement;
  8. using SmartBowSDK;
  9. using System;
  10. using HyperspaceGame;
  11. using MathNet.Numerics;
  12. public class GeneratingTarget : MonoBehaviour
  13. {
  14. // 最小时间间隔(秒)
  15. float _minTimeBetweenEvents = 1.0f;
  16. public float minTimeBetweenEvents { get { return _minTimeBetweenEvents; } set { _minTimeBetweenEvents = value; } }
  17. float _maxTimeBetweenEvents = 3.0f;// 最大时间间隔(秒)
  18. public float maxTimeBetweenEvents { get { return _maxTimeBetweenEvents; } set { _maxTimeBetweenEvents = value; } }
  19. public GameObject target;
  20. public Transform UI;
  21. public TextMeshProUGUI scoreUI;
  22. public TextMeshProUGUI scoreUI1;
  23. public Text countDownUI;
  24. public TextMeshProUGUI clipsizeUI;
  25. public TextMeshProUGUI hitCountUI;
  26. public TextMeshProUGUI shootRate;
  27. public GameObject GameOver;
  28. public Score scoreCom;
  29. public Score scoreCom1;
  30. public GameObject Miss;
  31. public Image grade;
  32. public Sprite[] gradeSprites;
  33. public Transform tp;
  34. public GameObject bulletNull;//子弹不足UI
  35. public GameObject[] bulletImages;//子弹图片数组
  36. public GameObject SelectLv;
  37. public Image imgSlider;
  38. public Text TopScore;
  39. public Text CurLvTxt;
  40. public Text MaxLvTxt;
  41. public int bulletCount;//子弹数量
  42. public int hitCount;//击中数量
  43. private float rate;//命中率
  44. public Button BtnRestart;
  45. public Button BtnNext;
  46. public Button BtnLast;
  47. int _score;
  48. public bool stop = false;
  49. public int score { get { return _score; }
  50. set {
  51. _score = value;
  52. ShowScore();
  53. }
  54. }
  55. /// <summary>
  56. /// 游戏时间
  57. /// </summary>
  58. private float countDownTime;
  59. int countDownTimeCache;
  60. /// <summary>
  61. /// 子弹数量
  62. /// </summary>
  63. private int clipsize;
  64. const int BulletCount = 15;
  65. /// <summary>
  66. /// 靶子存在最长时间
  67. /// </summary>
  68. float _targetExistenceTimeMax = 5;
  69. public float TargetExistenceTimeMax { get { return _targetExistenceTimeMax; } set { _targetExistenceTimeMax = value; } }
  70. /// <summary>
  71. /// 靶子存在最短时间
  72. /// </summary>
  73. float _targetExistenceTimeMin = 3;
  74. public float TargetExistenceTimeMin { get { return _targetExistenceTimeMin; } set { _targetExistenceTimeMin = value; } }
  75. float _scaleMin = 1.3f;
  76. public float ScaleMin { get { return _scaleMin; } set { _scaleMin = value; } }
  77. float _scaleMax = 1.8f;
  78. public float ScaleMax { get { return _scaleMax; } set { _scaleMax = value; } }
  79. public HyperspaceGame.Font font;
  80. public AudioSource ShootingSound;
  81. public AudioSource gameSatrtSound;
  82. public AudioClip[] gameSatrtClips;
  83. //public GameObject perfect;
  84. //public GameObject gaeat;
  85. //public GameObject good;
  86. //public Image goodImage;
  87. //public Image greatImage;
  88. public static GeneratingTarget gm { get; set; }
  89. public ShootingEvent shootingEvent;
  90. /// <summary>
  91. /// 记录当前射箭是否记录分数
  92. /// </summary>
  93. private bool bAddCountScore { get; set; } = false;
  94. [HideInInspector] public bool getAddCountScore => bAddCountScore;
  95. //分数统计
  96. [HideInInspector] public UserGameAnalyse1 userGameAnalyse1;
  97. public int Index = 0;
  98. private bool unload = false;
  99. /// <summary>
  100. /// 当前难度的配置
  101. /// </summary>
  102. public Level LvCfg = null;
  103. /// <summary>
  104. /// 当前序列的配置
  105. /// </summary>
  106. public Order orderCfg = null;
  107. float nextOrderWaitTime;
  108. int curOrderIdx;
  109. bool canEnterNextOrder = true;
  110. bool isbegin = false;
  111. int tragetLeftNum;
  112. /// <summary>
  113. /// 当前序列
  114. /// </summary>
  115. public int CurOrder = 0;
  116. public static int MaxLevel = 3;
  117. [SerializeField]
  118. RectTransform _canvasRectTransform;
  119. private void Awake()
  120. {
  121. gm = this;
  122. var scene = SceneManager.GetActiveScene();
  123. if(scene.name == "Hyperspace01")
  124. Index = 0;
  125. else if (scene.name == "Hyperspace02")
  126. Index = 1;
  127. else if(scene.name == "Hyperspace03")
  128. Index = 2;
  129. //初始化关卡配置
  130. LvCfg = Config.levels[Index];
  131. countDownTime = LvCfg.TotalTime;
  132. curOrderIdx = 0;
  133. UpdateCountDown(LvCfg.TotalTime);
  134. CurLvTxt.text = $"{Index + 1}";
  135. MaxLvTxt.text = $"/<color=#0F92D4>{MaxLevel}</color>";
  136. shootingEvent = FindObjectOfType<ShootingEvent>();
  137. scoreCom.gameObject.SetActive(false);
  138. scoreCom1.gameObject.SetActive(false);
  139. Miss.SetActive(false);
  140. stop = false;
  141. imgSlider.fillAmount = 1;
  142. ShowScore();
  143. bulletNull.SetActive(false);
  144. BtnRestart.onClick.AddListener(OnRestart);
  145. BtnNext.onClick.AddListener(OnBtnNext);
  146. BtnNext.gameObject.SetActive(Index + 1 < MaxLevel);
  147. BtnLast.onClick.AddListener(OnBtnLast);
  148. BtnLast.gameObject.SetActive(true);
  149. GameOver.SetActive(false);
  150. CreateUIManager();
  151. CreateTargetObject2D();
  152. }
  153. public void OnRestart()
  154. {
  155. Restart(Index);
  156. }
  157. public void OnBtnNext()
  158. {
  159. Restart(Index + 1);
  160. }
  161. public void OnBtnLast()
  162. {
  163. //Restart(Index - 1);
  164. gm = null;
  165. onUploadScore();
  166. //结束游戏页面
  167. userGameAnalyse1.UploadData(true);
  168. userGameAnalyse1.onResetOverlayData();
  169. SceneManager.LoadScene("Home", LoadSceneMode.Single);
  170. }
  171. void Start()
  172. {
  173. if (ShootCheck.ins.bluetoothDeviceStatus == BluetoothDeviceStatus.MagazineLoading)
  174. OnLoading();
  175. else
  176. OnSeparation();
  177. //Screen.SetResolution(1280, 720, false); // 设置分辨率为1920x1080,‌并设置为全屏模式
  178. Invoke("GameStart", 4);
  179. Game1();
  180. Invoke("Game2", 1);
  181. Invoke("Game3", 2);
  182. var canvases = FindObjectsByType<Canvas>(FindObjectsSortMode.InstanceID);
  183. foreach (var canvas in canvases)
  184. {
  185. if (canvas.name == "Canvas")
  186. {
  187. _canvasRectTransform = canvas.GetComponent<RectTransform>();
  188. break;
  189. }
  190. }
  191. //靶子默认状态
  192. var show = UIManager._ins.GetArrowBtnState();
  193. var arrow = shootingEvent.GetComponent<Image>();
  194. var color = arrow.color;
  195. if (show)
  196. color.a = 1;
  197. else
  198. color.a = 0;
  199. arrow.color = color;
  200. UIManager._ins.ShowQuit();
  201. }
  202. public void OpenSelectLevel()
  203. {
  204. SelectLv.SetActive(true);
  205. }
  206. public Vector2 GetCanvasSize()
  207. {
  208. return _canvasRectTransform.sizeDelta;
  209. }
  210. void Game1()
  211. {
  212. gameSatrtSound.clip = gameSatrtClips[0];
  213. gameSatrtSound.Play();
  214. }
  215. void Game2()
  216. {
  217. gameSatrtSound.clip = gameSatrtClips[1];
  218. gameSatrtSound.Play();
  219. }
  220. void Game3()
  221. {
  222. gameSatrtSound.clip = gameSatrtClips[2];
  223. gameSatrtSound.Play();
  224. }
  225. void GameStart()
  226. {
  227. isbegin = true;
  228. }
  229. private float reloadTime = 0;
  230. private void Reload(bool delay = false)
  231. {
  232. if (delay)
  233. {
  234. reloadTime = 3f;
  235. }
  236. else
  237. {
  238. clipsize = BulletCount;
  239. bulletCount -= font.Clip;
  240. bulletCount += clipsize;
  241. font.Clip = clipsize;
  242. bulletNull.SetActive(false);
  243. for (int i = 0; i < bulletImages.Length; i++)
  244. {
  245. bulletImages[i].SetActive(true);
  246. }
  247. }
  248. }
  249. public bool Reloading()
  250. {
  251. return unload;
  252. //return reloadTime > 0;
  253. }
  254. float _lastShootTime = 0;
  255. /// <summary>
  256. /// 射击
  257. /// </summary>
  258. /// <param name="bAddCount">是否是有效射箭</param>
  259. public void Shooting(bool bAddCount = false)
  260. {
  261. //加个间隔
  262. if (Time.realtimeSinceStartup - _lastShootTime < 0.5f) return;
  263. _lastShootTime = Time.realtimeSinceStartup;
  264. bAddCountScore = bAddCount;
  265. DoShoot();
  266. }
  267. private void DoShoot()
  268. {
  269. if (shootingEvent.ShootUIBtn())
  270. return;
  271. if (unload || clipsize <= 0)
  272. {
  273. Debug.Log("卸了弹夹 或者 没子弹了!");
  274. //没有子弹的声音
  275. //ShootingSound.Play();
  276. bulletImages[0].SetActive(false);
  277. bulletNull.SetActive(true);
  278. return;
  279. }
  280. else
  281. //正常发射的声音
  282. ShootingSound.Play();
  283. clipsize--;
  284. if (clipsize <= 0)
  285. {
  286. //Reload(true);//不自动装弹
  287. }
  288. font.Clip = clipsize;
  289. bulletImages[clipsize].SetActive(false);
  290. shootingEvent.OnShooting();
  291. }
  292. private void Update()
  293. {
  294. //if (reloadTime > 0)
  295. //{
  296. // reloadTime -= Time.deltaTime;
  297. // if (reloadTime <= 0)
  298. // Reload();
  299. //}
  300. #if UNITY_EDITOR
  301. if (Input.GetMouseButtonDown(0))
  302. {
  303. shootingEvent.OnPositionUpdate(Input.mousePosition);
  304. Shooting(true);
  305. }
  306. if (Input.GetKeyDown(KeyCode.W))
  307. {
  308. countDownTime = 0;
  309. }
  310. if (Input.GetKeyDown(KeyCode.R))
  311. {
  312. UIManager._ins.Reload();
  313. }
  314. #endif
  315. if (isbegin)
  316. {
  317. if (canEnterNextOrder)//靶子全消失了 开始走序列休息时间
  318. {
  319. if (nextOrderWaitTime <= 0)
  320. {
  321. //开始下一序列
  322. TriggerRandomEvent();
  323. }
  324. nextOrderWaitTime -= Time.deltaTime;
  325. }
  326. //游戏倒计时
  327. if (countDownTime <= 0)
  328. {
  329. //游戏时间到了 结束
  330. GameEnd();
  331. }
  332. else
  333. {
  334. countDownTime -= Time.deltaTime;
  335. var timeInt = Mathf.CeilToInt(countDownTime);
  336. if(timeInt != countDownTimeCache)
  337. {
  338. countDownTimeCache = timeInt;
  339. UpdateCountDown(countDownTimeCache);
  340. }
  341. imgSlider.fillAmount = countDownTime / (float)LvCfg.TotalTime;
  342. }
  343. if (curMoveCtrl != null && curMoveCtrl is IUpdate)
  344. {
  345. (curMoveCtrl as IUpdate).Update();
  346. }
  347. }
  348. }
  349. private void UpdateCountDown(int value)
  350. {
  351. countDownUI.text = $"{value}";
  352. }
  353. private void GameEnd()
  354. {
  355. stop = true;
  356. GameOver.SetActive(true);
  357. GameOverGrade(score);
  358. isbegin = false;
  359. countDownTimeCache = 0;
  360. //游戏结束上传分数
  361. onUploadScore();
  362. }
  363. /// <summary>
  364. /// 下一轮
  365. /// </summary>
  366. void TriggerRandomEvent()
  367. {
  368. canEnterNextOrder = false;
  369. Debug.Log($"新一轮创建 curOrderIdx={curOrderIdx}");
  370. if (LvCfg.orders.Length > curOrderIdx)
  371. {
  372. orderCfg = LvCfg.orders[curOrderIdx];
  373. CreateTargets();
  374. curOrderIdx++;
  375. }
  376. else
  377. GameEnd();
  378. }
  379. Dictionary<MoveType, Move> movesCtrl = new Dictionary<MoveType, Move>()
  380. {
  381. [MoveType.Stay] = new Stay(),
  382. [MoveType.VET] = new VET(),
  383. [MoveType.ROT] = new ROT(),
  384. [MoveType.W] = new W(),
  385. [MoveType.W2] = new W2(),
  386. [MoveType.RelativeHor] = new RelativeHor(),
  387. [MoveType.RelativeVet] = new RelativeVet(),
  388. [MoveType.HOR] = new HOR(),
  389. [MoveType.Diagonal] = new Diagonal(),
  390. [MoveType.LeftToRight] = new LeftToRight(),
  391. [MoveType.RightToLeft] = new RightToLeft(),
  392. };
  393. private Move curMoveCtrl;
  394. /// <summary>
  395. /// 创建当前轮靶子
  396. /// </summary>
  397. private void CreateTargets()
  398. {
  399. var createCount = orderCfg.Big + orderCfg.Middle + orderCfg.Small;
  400. Debug.Log($"创建数量 Big={orderCfg.Big} Middle={orderCfg.Middle} Small={orderCfg.Small}");
  401. tragetLeftNum = createCount;
  402. List<SpineAnimationLoader> gos = new List<SpineAnimationLoader>();
  403. for (int i = 0; i < createCount; i++)
  404. {
  405. var go = Instantiate(target, tp);
  406. var targetIns = go.GetComponent<SpineAnimationLoader>();
  407. if(i < orderCfg.Big)
  408. targetIns.Init(0.8f * 0.732f, orderCfg, OnTargetDestory);
  409. else if (i < orderCfg.Big + orderCfg.Middle)
  410. targetIns.Init(0.5f * 0.692f, orderCfg, OnTargetDestory);
  411. else
  412. targetIns.Init(0.3f * 0.733f, orderCfg, OnTargetDestory);
  413. go.SetActive(true);
  414. gos.Add(targetIns);
  415. }
  416. movesCtrl.TryGetValue(orderCfg.MoveType, out curMoveCtrl);
  417. if (curMoveCtrl == null)
  418. curMoveCtrl = movesCtrl[MoveType.Stay];
  419. curMoveCtrl.SetGo(gos);
  420. }
  421. /// <summary>
  422. /// 靶子被射击或者到时间销毁
  423. /// </summary>
  424. private void OnTargetDestory()
  425. {
  426. tragetLeftNum--;
  427. if (tragetLeftNum <= 0)
  428. {
  429. curMoveCtrl = null;
  430. Debug.Log("当前轮结束");
  431. canEnterNextOrder = true;
  432. //重置休息时间
  433. nextOrderWaitTime = orderCfg.WaitTime;
  434. }
  435. }
  436. public void ShowScore()
  437. {
  438. //font.Text = score;
  439. TopScore.text = score.ToString().PadLeft(3, '0');
  440. }
  441. public Score scoreSprite;
  442. public void ShowScoreCom(int score, Vector3 pos, Vector2 scorepos, Transform tf, int posIdx)
  443. {
  444. Debug.Log($"得分 score{score}");
  445. if (score >= 6)
  446. {
  447. var go = GameObject.Instantiate(scoreCom, pos, Quaternion.identity, _canvasRectTransform);
  448. go.gameObject.SetActive(true);
  449. go.transform.localScale = Vector3.one * 0.55f;
  450. go.ShowScore(score, scorepos);
  451. }
  452. else
  453. {
  454. var go = GameObject.Instantiate(scoreCom1, tf.position, Quaternion.identity, _canvasRectTransform);
  455. go.gameObject.SetActive(true);
  456. var halfRadius = 547f * 0.5f;
  457. var offest = tf.localScale.x * halfRadius + 80f;
  458. var x = (posIdx == 1 || posIdx == 2) ? offest : -offest;
  459. var y = (posIdx == 1 || posIdx == 4) ? offest : -offest;
  460. go.ShowScore(score, new Vector3(x, y, 0));
  461. }
  462. }
  463. public void ShowMiss(Vector3 position)
  464. {
  465. if (stop)
  466. return;
  467. var go = GameObject.Instantiate(Miss, position, Quaternion.identity, _canvasRectTransform);
  468. go.AddComponent<CountDown>();
  469. go.SetActive(true);
  470. }
  471. public void GameOverGrade(int score)
  472. {
  473. hitCountUI.text = hitCount.ToString();
  474. var bulletUse = bulletCount - font.Clip;
  475. clipsizeUI.text = bulletUse.ToString();
  476. float rate = 0;
  477. if (hitCount != 0)
  478. rate = (float)hitCount / (float)bulletUse;
  479. if(rate == 0)
  480. {
  481. rate = 0;
  482. }
  483. shootRate.text = string.Format("{0:P0}", rate);
  484. //font.ShowOverScore();
  485. font.Text = score;
  486. if (score < 20)
  487. {
  488. Debug.Log("游戏失败");
  489. grade.sprite = gradeSprites[0];
  490. return;
  491. }
  492. if (score > 50)
  493. {
  494. Debug.Log("完美");
  495. grade.sprite = gradeSprites[1];
  496. return;
  497. }
  498. if (score >= 20 && score <= 30)
  499. {
  500. Debug.Log("合格");
  501. grade.sprite = gradeSprites[2];
  502. return;
  503. }
  504. if (score > 30 && score <= 50)
  505. {
  506. Debug.Log("优秀");
  507. grade.sprite = gradeSprites[3];
  508. return;
  509. }
  510. }
  511. public void Restart(int index)
  512. {
  513. string name = "";
  514. if (index == 0)
  515. name = "Hyperspace01";
  516. else if (index == 1)
  517. name = "Hyperspace02";
  518. else if (index == 2)
  519. name = "Hyperspace03";
  520. SceneManager.LoadScene(name);
  521. }
  522. //public void SetTarget(int index)
  523. //{
  524. // goodImage.sprite = font.sprites[index];
  525. // good.SetActive(true);
  526. //}
  527. //public void SetGreat(int index)
  528. //{
  529. // greatImage.sprite = font.sprites[index];
  530. // gaeat.SetActive(true);
  531. //}
  532. /// <summary>
  533. /// 弹夹分离
  534. /// </summary>
  535. public void OnSeparation()
  536. {
  537. unload = true;
  538. clipsize = 0;
  539. bulletCount -= font.Clip;
  540. font.Clip = clipsize;
  541. }
  542. /// <summary>
  543. /// 弹夹上膛
  544. /// </summary>
  545. public void OnLoading()
  546. {
  547. unload = false;
  548. Reload();
  549. }
  550. #region 新增 UIManager 和 TargetObject2D
  551. private GameObject uiManagerInstance;
  552. private GameObject targetObject2D;
  553. // 动态加载并生成 UIManager
  554. public void CreateUIManager()
  555. {
  556. GameObject uiManagerPrefab = Resources.Load<GameObject>("UIManager"); // 从 Resources 中加载 UIManager 预制
  557. uiManagerInstance = Instantiate(uiManagerPrefab); // 实例化 UIManager
  558. //管理分数上传
  559. userGameAnalyse1 = UserGameAnalyse1.CreateWhenGameStartAndReturn(16);
  560. }
  561. //校准靶子
  562. public void CreateTargetObject2D() {
  563. GameObject targetObject2DPrefab = Resources.Load<GameObject>("TargetObject2D");
  564. targetObject2D = Instantiate(targetObject2DPrefab, UI);
  565. }
  566. // 销毁 UIManager 实例
  567. public void DestroyUIManager()
  568. {
  569. if (UIManager._ins != null)
  570. {
  571. Destroy(UIManager._ins.gameObject); // 销毁 UIManager 实例
  572. uiManagerInstance = null;
  573. }
  574. }
  575. /// <summary>
  576. /// 射击次数
  577. /// </summary>
  578. /// <param name="count"></param>
  579. public void onShootCount(int count)
  580. {
  581. userGameAnalyse1.changeShootingCount(count);
  582. }
  583. /// <summary>
  584. /// 上传分数到服务器
  585. /// </summary>
  586. public void onUploadScore()
  587. {
  588. if (_score > 0)
  589. {
  590. Debug.Log("上传的积分为:" + _score);
  591. RankComp.Instance.uploadSinglePlayerGameRes(_score);
  592. _score = 0;
  593. }
  594. }
  595. #endregion
  596. }