GeneratingTarget.cs 18 KB

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