TZFEGameVIew.cs 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using cfg.GfgCfg;
  5. using ET;
  6. using FairyGUI;
  7. using UI.MiniGame;
  8. using UnityEngine;
  9. namespace GFGGame
  10. {
  11. public class TZFEGameView : BaseWindow
  12. {
  13. private UI_TZFEGameView _ui;
  14. private int[,] Map;
  15. enum Direction
  16. {
  17. up,
  18. down,
  19. left,
  20. right
  21. };
  22. private Vector2 touchFirst = Vector2.zero; //手指开始按下的位置
  23. private Vector2 touchSecond = Vector2.zero; //手指拖动的位置
  24. private System.Random rand;
  25. //这个是数组的行数和列数,mapLength一般采用行列一样
  26. private int rows = 4;
  27. private int columns = 4;
  28. private int mapLength = 5;
  29. //得分
  30. private int score = 0;
  31. private int scoreMax = 0;
  32. //目标分数
  33. private int targetNum = 128;
  34. private int gameID;
  35. private Merge2048GameCfg gameDate;
  36. private List<ActivityOpenCfg> activityGameDate;
  37. //评价
  38. private List<int> CustemsNum = new List<int>()
  39. {
  40. 0,
  41. 0,
  42. 0,
  43. };
  44. private bool isMove;
  45. private bool isMerge;
  46. private struct NumPos
  47. {
  48. public int x;
  49. public int y;
  50. public bool isCreat;
  51. }
  52. //需要播放动效的列表
  53. private List<NumPos> numPosArray = new List<NumPos>();
  54. private int time = 0;
  55. private EffectUI _effectUI1;
  56. public override void Dispose()
  57. {
  58. EffectUIPool.Recycle(_effectUI1);
  59. _effectUI1 = null;
  60. if (_ui != null)
  61. {
  62. _ui.Dispose();
  63. _ui = null;
  64. }
  65. base.Dispose();
  66. }
  67. protected override void OnInit()
  68. {
  69. base.OnInit();
  70. packageName = UI_TZFEGameView.PACKAGE_NAME;
  71. _ui = UI_TZFEGameView.Create();
  72. this.viewCom = _ui.target;
  73. isfullScreen = true;
  74. isReturnView = true;
  75. _ui.m_numList.itemRenderer = ListNumItem;
  76. _ui.m_mask.onTouchBegin.Add(OnClickBegin);
  77. _ui.m_mask.onTouchEnd.Add(OnClickEnd);
  78. _ui.m_backBtn.onClick.Add(OnClickBtnBack);
  79. _ui.m_mergeBtn.onClick.Add(OnClickMergeTips);
  80. Map = new int[rows, columns];
  81. _effectUI1 = EffectUIPool.CreateEffectUI(_ui.m_effectTitle, "ui_Activity", "SGLL_Game_Text");
  82. }
  83. protected override void OnShown()
  84. {
  85. base.OnShown();
  86. if ((this.viewData as object[]).Length != 0 && this.viewData != null)
  87. {
  88. gameID = (int)(this.viewData as object[])[0];
  89. }
  90. else
  91. {
  92. gameID = 128;
  93. }
  94. gameDate = CommonDataManager.Tables.TblMerge2048GameCfg.GetOrDefault(gameID);
  95. activityGameDate = CommonDataManager.Tables.TblActivityOpenCfg.DataList
  96. .Where(a => a.Type == ConstLimitTimeActivityType.ActLimitStlyc).ToList();
  97. InitMap();
  98. UpdateView();
  99. UpdateList();
  100. }
  101. protected override void OnHide()
  102. {
  103. Timers.inst.Remove(UpdateTime);
  104. base.OnHide();
  105. }
  106. private void OnClickBtnBack()
  107. {
  108. string exitTip;
  109. if (gameDate.BonusLose.Count == 0)
  110. {
  111. exitTip = "退出游戏不保存进度,不扣除任何次数和道具,是否退出?";
  112. }
  113. else
  114. {
  115. exitTip = "退出游戏会按失败结算,获得80%的奖励,是否退出?";
  116. }
  117. AlertUI.Show(exitTip)
  118. .SetLeftButton(true, "取消", (object data) => { })
  119. .SetRightButton(true, "确定", async (object data) =>
  120. {
  121. var result = await MiniGameProxy.ReqMiniGameEnd(gameID, gameDate.Type, time, false,
  122. activityGameDate[0].Id, true);
  123. this.Hide();
  124. });
  125. }
  126. private void InitMap()
  127. {
  128. for (int i = 0; i < rows; i++)
  129. for (int j = 0; j < columns; j++)
  130. {
  131. Map[i, j] = 0;
  132. }
  133. }
  134. private void UpdateView()
  135. {
  136. time = 1;
  137. score = 0;
  138. targetNum = CommonDataManager.Tables.TblMerge2048GameCfg.GetOrDefault(gameID).TargetNum;
  139. CustemsNum[0] = CommonDataManager.Tables.TblMerge2048GameCfg.GetOrDefault(gameID).TimeStar3;
  140. CustemsNum[1] = CommonDataManager.Tables.TblMerge2048GameCfg.GetOrDefault(gameID).TimeStar2;
  141. CustemsNum[2] = CommonDataManager.Tables.TblMerge2048GameCfg.GetOrDefault(gameID).TimeStar1;
  142. _ui.m_star3.url = "ui://MiniGame/tb_zx_pt_star";
  143. _ui.m_target.url = ResPathUtil.GetMiniGamePicPath(
  144. CommonDataManager.Tables.TblMerge2048Cfg.DataList
  145. .Where(a => a.Id == gameDate.SubType && a.Num == targetNum).ToList()[0].ResName,
  146. "TZFEGame");
  147. _ui.m_score.text = string.Format("分数:{0}", score.ToString());
  148. _ui.m_score.visible = false;
  149. _ui.m_time.visible = false;
  150. _ui.m_timeNum.visible = false;
  151. _ui.m_title.visible = false;
  152. rand = new System.Random();
  153. UpdateStar();
  154. Timers.inst.Add(1.0f, 0, UpdateTime);
  155. }
  156. private void UpdateScore()
  157. {
  158. _ui.m_score.text = string.Format("分数:{0}", score.ToString());
  159. }
  160. private void UpdateList()
  161. {
  162. RandomCreateNum();
  163. _ui.m_numList.numItems = rows * columns;
  164. }
  165. private void ListNumItem(int index, GObject item)
  166. {
  167. UI_numItem numItem = UI_numItem.Proxy(item);
  168. int x = index / rows;
  169. int y = index % columns;
  170. if (Map[x, y] == 0)
  171. {
  172. numItem.m_icon.visible = false;
  173. }
  174. else
  175. {
  176. //numItem.m_icon.url = string.Format("ui://MiniGame/sgll2_{0}", Map[x, y]);
  177. numItem.m_icon.url = ResPathUtil.GetMiniGamePicPath(
  178. CommonDataManager.Tables.TblMerge2048Cfg.DataList
  179. .Where(a => a.Id == gameDate.SubType && a.Num == Map[x, y]).ToList()[0].ResName, "TZFEGame");
  180. numItem.m_icon.visible = true;
  181. }
  182. //播放生成和合并动效
  183. for (int i = 0; i < numPosArray.Count; i++)
  184. {
  185. if (x == numPosArray[i].x && y == numPosArray[i].y)
  186. {
  187. if (numPosArray[i].isCreat)
  188. {
  189. numItem.m_t0.Play();
  190. numPosArray.RemoveAt(i);
  191. break;
  192. }
  193. else
  194. {
  195. numItem.m_t1.Play();
  196. numPosArray.RemoveAt(i);
  197. break;
  198. }
  199. }
  200. }
  201. UI_numItem.ProxyEnd();
  202. }
  203. //随机生成数字2(%90),4(%10)
  204. private void RandomCreateNum()
  205. {
  206. bool gameOver = false;
  207. for (int i = 0; i < rows; i++)
  208. {
  209. for (int j = 0; j < columns; j++)
  210. {
  211. if (Map[i, j] == 0)
  212. {
  213. gameOver = true;
  214. break;
  215. }
  216. }
  217. }
  218. if (!gameOver)
  219. {
  220. //GameOver(false);
  221. return;
  222. }
  223. while (true)
  224. {
  225. int x = rand.Next(0, rows);
  226. int y = rand.Next(0, columns);
  227. NumPos item;
  228. int num;
  229. int randNum = rand.Next(1, 11);
  230. if (randNum <= 9)
  231. {
  232. num = 2;
  233. }
  234. else
  235. {
  236. num = 4;
  237. }
  238. if (Map[x, y] == 0)
  239. {
  240. Map[x, y] = num;
  241. item.x = x;
  242. item.y = y;
  243. item.isCreat = true;
  244. numPosArray.Add(item);
  245. break;
  246. }
  247. }
  248. }
  249. /// <summary>
  250. /// 去零
  251. /// </summary>
  252. /// <param name="row">对于一行或一列元素</param>
  253. private void Remove0(int[] row, Direction dir, int xy = 0)
  254. {
  255. int pos = 0;
  256. int[] rowB = new int[row.Length];
  257. for (int i = 0; i < row.Length; i++)
  258. {
  259. rowB[i] = row[i];
  260. }
  261. for (int i = 0; i < row.Length; ++i)
  262. {
  263. if (row[i] != 0)
  264. {
  265. row[pos] = row[i];
  266. //-----这里修改需要播放动效的数字位置列表-----
  267. int x = 0;
  268. int y = 0;
  269. int nextX = 0;
  270. int nextY = 0;
  271. for (int t = 0; t < numPosArray.Count; t++)
  272. {
  273. switch (dir)
  274. {
  275. case Direction.up:
  276. x = i;
  277. y = xy;
  278. nextX = pos;
  279. nextY = xy;
  280. break;
  281. case Direction.down:
  282. x = row.Length - 1 - i;
  283. y = xy;
  284. nextX = row.Length - 1 - pos;
  285. nextY = xy;
  286. break;
  287. case Direction.left:
  288. x = xy;
  289. y = i;
  290. nextX = xy;
  291. nextY = pos;
  292. break;
  293. case Direction.right:
  294. x = xy;
  295. y = row.Length - 1 - i;
  296. nextX = xy;
  297. nextY = row.Length - 1 - pos;
  298. break;
  299. }
  300. if (numPosArray.Count != 0 && numPosArray[t].x == x && numPosArray[t].y == y && pos != i)
  301. {
  302. numPosArray.RemoveAt(t);
  303. NumPos item;
  304. item.x = nextX;
  305. item.y = nextY;
  306. item.isCreat = false;
  307. numPosArray.Add(item);
  308. }
  309. }
  310. //---------------------------------------
  311. pos++;
  312. }
  313. }
  314. for (; pos < row.Length; ++pos) row[pos] = 0;
  315. for (int i = 0; i < row.Length; i++)
  316. {
  317. if (row[i] != rowB[i])
  318. {
  319. isMove = true;
  320. }
  321. }
  322. }
  323. /// <summary>
  324. /// 合并
  325. /// </summary>
  326. /// <param name="row">对于一行或一列元素,完成一次向左合并的操作</param>
  327. private void Merge(int[] row, Direction dir, int xy)
  328. {
  329. Remove0(row, dir, xy);
  330. // 相邻相同则合并
  331. for (int i = 0; i < row.Length - 1; ++i)
  332. {
  333. if (row[i] != 0 && row[i] == row[i + 1])
  334. {
  335. row[i] *= 2;
  336. row[i + 1] = 0;
  337. //将合并的数字放入列表
  338. NumPos item;
  339. item = MoveAddNum(i, xy, dir, row.Length - 1);
  340. numPosArray.Add(item);
  341. //-------
  342. score += row[i];
  343. UpdateScore();
  344. if (row[i] == targetNum)
  345. {
  346. //游戏成功
  347. GameOver(true);
  348. }
  349. isMerge = true;
  350. }
  351. }
  352. Remove0(row, dir, xy);
  353. }
  354. //将合并的数字位置放入列表的准备
  355. private NumPos MoveAddNum(int i, int xy, Direction dir, int length)
  356. {
  357. NumPos item = new NumPos();
  358. switch (dir)
  359. {
  360. case Direction.up:
  361. item.x = i;
  362. item.y = xy;
  363. item.isCreat = false;
  364. break;
  365. case Direction.down:
  366. item.x = length - i;
  367. item.y = xy;
  368. item.isCreat = false;
  369. break;
  370. case Direction.left:
  371. item.x = xy;
  372. item.y = i;
  373. item.isCreat = false;
  374. break;
  375. case Direction.right:
  376. item.x = xy;
  377. item.y = length - i;
  378. item.isCreat = false;
  379. break;
  380. }
  381. return item;
  382. }
  383. /// <summary>
  384. /// 上移
  385. /// </summary>
  386. /// <param name="map">原棋盘</param>
  387. /// <returns></returns>
  388. private void Up(int[,] map)
  389. {
  390. int[] arr = new int[rows];
  391. for (int j = 0; j < columns; ++j)
  392. {
  393. for (int i = 0; i < rows; ++i)
  394. {
  395. arr[i] = map[i, j];
  396. }
  397. Merge(arr, Direction.up, j);
  398. for (int i = 0; i < rows; ++i) map[i, j] = arr[i];
  399. }
  400. }
  401. /// <summary>
  402. /// 下移
  403. /// </summary>
  404. private int[,] Down(int[,] map)
  405. {
  406. int[] arr = new int[rows];
  407. for (int j = 0; j < columns; ++j)
  408. {
  409. for (int i = 0; i < rows; ++i)
  410. {
  411. arr[rows - 1 - i] = map[i, j];
  412. }
  413. Merge(arr, Direction.down, j);
  414. for (int i = 0; i < rows; ++i) map[i, j] = arr[rows - 1 - i];
  415. }
  416. return map;
  417. }
  418. /// <summary>
  419. /// 左移
  420. /// </summary>
  421. private int[,] Left(int[,] map)
  422. {
  423. int[] arr = new int[columns];
  424. for (int i = 0; i < rows; ++i)
  425. {
  426. for (int j = 0; j < columns; ++j)
  427. {
  428. arr[j] = map[i, j];
  429. }
  430. Merge(arr, Direction.left, i);
  431. for (int j = 0; j < columns; ++j) map[i, j] = arr[j];
  432. }
  433. return map;
  434. }
  435. /// <summary>
  436. /// 右移
  437. /// </summary>
  438. private int[,] Right(int[,] map)
  439. {
  440. int[] arr = new int[columns];
  441. for (int i = 0; i < rows; ++i)
  442. {
  443. for (int j = 0; j < columns; ++j)
  444. {
  445. arr[columns - 1 - j] = map[i, j];
  446. }
  447. Merge(arr, Direction.right, i);
  448. for (int j = 0; j < columns; ++j) map[i, j] = arr[columns - 1 - j];
  449. }
  450. return map;
  451. }
  452. /// <summary>
  453. /// 进行一次移动操作
  454. /// </summary>
  455. /// <param name="map">原棋盘</param>
  456. /// <param name="dir">移动的方向(枚举)</param>
  457. private void Move(int[,] map, Direction dir)
  458. {
  459. switch (dir)
  460. {
  461. case Direction.up:
  462. Up(map); break;
  463. case Direction.down:
  464. Down(map); break;
  465. case Direction.left:
  466. Left(map); break;
  467. case Direction.right:
  468. Right(map); break;
  469. }
  470. if (isMerge || isMove)
  471. {
  472. isMove = false;
  473. isMerge = false;
  474. UpdateList();
  475. numPosArray.Clear();
  476. }
  477. else
  478. {
  479. CheckArray();
  480. }
  481. }
  482. private void OnClickBegin()
  483. {
  484. touchFirst = Input.mousePosition; //记录开始按下的位置
  485. }
  486. private void OnClickEnd()
  487. {
  488. touchSecond = Input.mousePosition; //记录拖动的位置
  489. if (touchSecond.x < touchFirst.x &&
  490. Math.Abs(touchSecond.x - touchFirst.x) > Math.Abs(touchSecond.y - touchFirst.y))
  491. {
  492. //向左滑动
  493. Move(Map, Direction.left);
  494. }
  495. if (touchSecond.x > touchFirst.x &&
  496. Math.Abs(touchSecond.x - touchFirst.x) > Math.Abs(touchSecond.y - touchFirst.y))
  497. {
  498. //向右滑动
  499. Move(Map, Direction.right);
  500. }
  501. if (touchSecond.y < touchFirst.y &&
  502. Math.Abs(touchSecond.y - touchFirst.y) > Math.Abs(touchSecond.x - touchFirst.x))
  503. {
  504. //向下滑动
  505. Move(Map, Direction.down);
  506. }
  507. if (touchSecond.y > touchFirst.y &&
  508. Math.Abs(touchSecond.y - touchFirst.y) > Math.Abs(touchSecond.x - touchFirst.x))
  509. {
  510. //向上滑动
  511. Move(Map, Direction.up);
  512. }
  513. touchFirst = touchSecond;
  514. }
  515. private void OnClickMergeTips()
  516. {
  517. ViewManager.Show<SyntheticRoutetipView>(new object[] { targetNum, gameDate.SubType });
  518. }
  519. private void UpdateTime(object param = null)
  520. {
  521. _ui.m_timeNum.text = sec_to_hms(time);
  522. time++;
  523. //UpdateStar();
  524. }
  525. private void UpdateStar()
  526. {
  527. int starNum = 0;
  528. for (int i = CustemsNum.Count - 1; i >= 0; i--)
  529. {
  530. if (time <= CustemsNum[i])
  531. {
  532. starNum += 1;
  533. }
  534. }
  535. switch (starNum)
  536. {
  537. case 1:
  538. _ui.m_star1.url = "ui://MiniGame/tb_zx_pt_star";
  539. _ui.m_star2.url = "ui://MiniGame/tb_zx_pt_star_grey";
  540. _ui.m_star3.url = "ui://MiniGame/tb_zx_pt_star_grey";
  541. break;
  542. case 2:
  543. _ui.m_star1.url = "ui://MiniGame/tb_zx_pt_star";
  544. _ui.m_star2.url = "ui://MiniGame/tb_zx_pt_star";
  545. _ui.m_star3.url = "ui://MiniGame/tb_zx_pt_star_grey";
  546. break;
  547. case 3:
  548. _ui.m_star1.url = "ui://MiniGame/tb_zx_pt_star";
  549. _ui.m_star2.url = "ui://MiniGame/tb_zx_pt_star";
  550. _ui.m_star3.url = "ui://MiniGame/tb_zx_pt_star";
  551. break;
  552. default:
  553. _ui.m_star1.visible = false;
  554. _ui.m_star2.visible = false;
  555. _ui.m_star3.visible = false;
  556. break;
  557. }
  558. }
  559. //将秒数转化为时分秒 duration为秒数
  560. private string sec_to_hms(int duration)
  561. {
  562. TimeSpan ts = new TimeSpan(0, 0, duration);
  563. int _hours = 0;
  564. if (ts.Days > 0)
  565. {
  566. _hours = ts.Days * 24;
  567. }
  568. string str = "";
  569. if (ts.Hours > 0)
  570. {
  571. str = String.Format("{0:00}", ts.Hours + _hours) + ":" + String.Format("{0:00}", ts.Minutes) + ":" +
  572. String.Format("{0:00}", ts.Seconds);
  573. }
  574. if (ts.Hours == 0 && ts.Minutes > 0)
  575. {
  576. str = "00:";
  577. if (_hours > 0)
  578. {
  579. str = String.Format("{0:00}", ts.Hours + _hours) + ":";
  580. }
  581. str += String.Format("{0:00}", ts.Minutes) + ":" + String.Format("{0:00}", ts.Seconds);
  582. }
  583. if (ts.Hours == 0 && ts.Minutes == 0)
  584. {
  585. str = "00";
  586. if (_hours > 0)
  587. {
  588. str = String.Format("{0:00}", ts.Hours + _hours);
  589. }
  590. str += ":00:" + String.Format("{0:00}", ts.Seconds);
  591. }
  592. return str;
  593. }
  594. private void CheckArray()
  595. {
  596. bool gameOver = false;
  597. for (int i = 0; i < rows; i++)
  598. {
  599. for (int j = 0; j < columns; j++)
  600. {
  601. if (Map[i, j] == 0)
  602. {
  603. gameOver = true;
  604. break;
  605. }
  606. }
  607. }
  608. if (!gameOver)
  609. {
  610. // 游戏结束
  611. GameOver(false);
  612. return;
  613. }
  614. }
  615. private void GameOver(bool target)
  616. {
  617. Timers.inst.Remove(UpdateTime);
  618. ViewManager.Show<ResultTipsView>(new object[] { target, gameDate.Type, time, gameDate.Id });
  619. }
  620. }
  621. }