GameRollNode.ts 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583
  1. import { _decorator, Component, Node, Prefab, instantiate, Vec3, tween, math, Game, UITransform, Tween, Label, UIOpacity} from 'cc';
  2. import { Item } from './Item';
  3. import { GameConstant } from './GameConstant';
  4. import { GameScene } from './GameScene';
  5. const { ccclass, property } = _decorator;
  6. @ccclass('GameRollNode')
  7. export class GameRollNode extends Component {
  8. @property(Prefab)
  9. item: Prefab = null;
  10. @property(Node)
  11. slotRollView: Node = null;
  12. @property(Node)
  13. rollSpine: Node = null;
  14. @property(Node)
  15. endNode: Node = null;
  16. @property(Node)
  17. winDetail: Node = null;
  18. @property(Node)
  19. winDetailIcons: Node = null;
  20. @property(Node)
  21. winDetailLabel: Node = null;
  22. public rollNodes = [];
  23. public rollNodeIcons = [];
  24. public resultRollNodes = [];
  25. public resultRollIcons = [];
  26. public resultValues = [];
  27. public resultIcons = [];
  28. public resultWildTimes = [];
  29. public tempValueIsHaveScatter = [];
  30. public rollBgIsScroll = [];
  31. public rollBgisStop = [];
  32. public isScroll = false;
  33. public startRollTime = 0;
  34. public isFast = false;
  35. public freeIconCount = 0;
  36. public isFastStop = false;
  37. public fastIndex = 0;
  38. public bGameEnd = true;
  39. public delayTime = 0;
  40. public bQuick = false;
  41. public hasSpecial = false;
  42. public isInScatterGame = false;
  43. public rollResultData = {
  44. "m_desk_data": [[2,2,2,2,2,2],[2,2,2,2,2,2],[2,2,2,2,2,2],[2,2,2,2,2,2]],
  45. "m_wildTimes_data": [[0,0,0,0,0,0],[0,0,0,0,0,0],[0,0,0,0,0,0],[0,0,0,0,0,0]],
  46. "m_isSpecialGame": 0,
  47. "m_freeCount": 0,
  48. "m_freeCountAdd": 0,
  49. "m_betIndex": 0,
  50. "m_lottery_size": 0,
  51. "m_lCurScore":0,
  52. "m_line_icon": [[2,2,2,2,2,2],[2,2,2,2,2],[2,2,2,2],[2,2,2]],
  53. "m_line_size": [6,5,4,3],
  54. "m_line_icon_active": [[1,1,1,1,1,1],[1,1,1,1,1],[1,1,1,1],[1,1,1]],
  55. "m_line_times": [500,500,500,500],
  56. "m_line_index": [[0,1,2,3,4,5],[6,7,8,9,10,11],[12,13,14,15,16,17],[18,19,20,21,22,23]],
  57. };
  58. start() {
  59. for (let i = 0; i < GameConstant.MAX_COL; i++) {
  60. this.rollNodes[i] = this.slotRollView.getChildByName("roll" + i);
  61. this.resultRollNodes[i] = this.slotRollView.getChildByName("result_roll" + i);
  62. }
  63. let itemHeight = 190;
  64. let iconIndex = 0;
  65. for (let i = 0; i < this.rollNodes.length; i++) {
  66. this.rollNodeIcons[i] = [];
  67. this.resultValues[i] = [];
  68. this.resultRollIcons[i] = [];
  69. this.resultWildTimes[i] = [];
  70. for (let j = 0; j < GameConstant.COL_ITEM_LEN; j++) {
  71. let item = instantiate(this.item);
  72. item.position = new Vec3(0, (GameConstant.COL_ITEM_LEN / 2 - 0.5 - j) * itemHeight, 0);
  73. item.parent = this.rollNodes[i];
  74. this.rollNodeIcons[i][j] = item;
  75. let iconType = j >= 11 ? 2 : (2 + j);
  76. let resultItem = instantiate(this.item);
  77. resultItem.position = new Vec3(0, (GameConstant.COL_ITEM_LEN / 2 - 0.5 - j) * itemHeight, 0);
  78. resultItem.parent = this.resultRollNodes[i];
  79. resultItem.getComponent(Item).setIconType(GameConstant.getRandomNumber(2, GameConstant.MAX_ICON_TYPE), true);
  80. // resultItem.active = false;
  81. this.resultRollIcons[i][j] = resultItem;
  82. if (j >= 4 && j < 8) {
  83. // this.resultValues[i][j - 4] = iconIndex++ % 13;//GameConstant.getRandomNumber(2, GameConstant.MAX_ICON_TYPE);
  84. this.resultValues[i][j - 4] = this.rollResultData.m_desk_data[j - 4][i];
  85. resultItem.getComponent(Item).setIconType(this.resultValues[i][j - 4], true);
  86. }
  87. if (resultItem.getComponent(Item).getIconType() == GameConstant.ICON_TYPE.SYMBOL_WILD) {
  88. this.resultWildTimes[i][j] = GameConstant.WILD_TIMES[GameConstant.getRandomNumber(0, 3)];
  89. }
  90. }
  91. }
  92. for (let i = 0; i < GameConstant.MAX_COL; i++) {
  93. this.resultIcons[i] = [];
  94. for (let j = 0; j < GameConstant.MAX_ROW; j++) {
  95. let resultItem = instantiate(this.item);
  96. resultItem.position = new Vec3(this.rollNodes[i].position.x, (GameConstant.MAX_ROW / 2 - 0.5 - j) * itemHeight, 0);
  97. resultItem.parent = this.endNode;
  98. resultItem.getComponent(Item).setIconType(this.resultValues[i][j], true);//
  99. this.resultIcons[i][j] = resultItem;
  100. }
  101. }
  102. // this.slotRollView.parent.scale = new Vec3(0.1,0.1,0.1);
  103. this.endNode.active = true;
  104. }
  105. // 展示结果图标
  106. showResultIcons(i) {
  107. this.endNode.active = true;
  108. this.resultRollNodes[i].active = false;
  109. for (let j = 0; j < GameConstant.MAX_ROW; j++) {
  110. this.resultIcons[i][j].active = true;
  111. }
  112. }
  113. // 重置展示结果的图标状态
  114. resetResultIcons() {
  115. console.log("resetResultIcons");
  116. this.endNode.active = false;
  117. for (let i = 0; i < GameConstant.MAX_COL; i++) {
  118. for (let j = 0; j < GameConstant.MAX_ROW; j++) {
  119. this.resultIcons[i][j].getComponent(Item).showNormal();
  120. this.resultIcons[i][j].active = false;
  121. }
  122. }
  123. }
  124. // 设置图标为模糊图片
  125. resetRollingItemValue(i) {
  126. for(let j = 0; j < GameConstant.COL_ITEM_LEN; ++j) {
  127. var randType = GameConstant.getRandomNumber(2, GameConstant.MAX_ICON_TYPE)
  128. this.rollNodeIcons[i][j].getComponent(Item).setIconType(randType, false);
  129. this.resultRollIcons[i][j].getComponent(Item).setIconType(randType, false);
  130. }
  131. }
  132. // 开始转动函数
  133. startRollActions() {
  134. this.bGameEnd = false;
  135. // 停止结果细节的节点动作,并隐藏节点
  136. Tween.stopAllByTarget(this.winDetail);//.getComponent(UIOpacity)
  137. this.winDetail.active = false;
  138. Tween.stopAllByTarget(this.node);
  139. // 重置结果图标的状态
  140. this.resetResultIcons();
  141. // 重置转动状态参数
  142. for(let i = 0; i < GameConstant.MAX_COL; ++i) {
  143. this.tempValueIsHaveScatter[i] = false;
  144. this.rollBgIsScroll[i] = false;
  145. this.rollBgisStop[i] = false;
  146. }
  147. // 开始滚动
  148. for(let i = 0; i < GameConstant.MAX_COL; ++i) {
  149. let rollbg = this.resultRollNodes[i];
  150. // 展示滚动层,停止滚动层动作
  151. rollbg.active = true;
  152. Tween.stopAllByTarget(rollbg);
  153. this.rollNodes[i].y = rollbg.y + rollbg.getComponent(UITransform).height;
  154. // 开始转动前的上提动作
  155. tween(rollbg)
  156. .delay(0.1 * i)
  157. .by(0.2, {y: 60})
  158. .by(0.05, {y: -15})
  159. // .by(0.2, {y: 40}, {easing: 'sineOut'})
  160. // .by(0.2, {y: -20}, {easing: 'sineIn'})
  161. .call(()=>{
  162. this.rollNodes[i].y += 60;
  163. if (i == 0) {
  164. this.isScroll = true;
  165. }
  166. this.rollBgIsScroll[i] = true;
  167. })
  168. .delay(0.05)
  169. .call(()=>{
  170. this.resetRollingItemValue(i);
  171. })
  172. .start();
  173. }
  174. this.startRollTime = new Date().getTime();
  175. }
  176. // 每列转动结束的函数
  177. rollEnds(i) {
  178. if(i == 0) {
  179. this.node.parent.getComponent(GameScene).onGameEnd();
  180. }
  181. // 如果有两列有进入小游戏的特殊图标则快速转动
  182. let fastDelayTime = 0
  183. if(this.freeIconCount >= 2 && (i >= 3 && i < 6) && !this.isFastStop) {
  184. if (this.fastIndex != i) {
  185. this.fastIndex = i;
  186. this.isFast = true;
  187. fastDelayTime = 2;
  188. this.rollBgIsScroll[i] = true;
  189. this.rollSpine.x = this.rollNodes[i].x;
  190. this.rollSpine.active = true;
  191. var delayPlaySoundTime = i >= 3 ? 1.0 : 0.5;
  192. tween(this.node)
  193. .delay(delayPlaySoundTime)
  194. .call(()=>{
  195. // this.playEffect(i == 3 ? "fast_1" : "fast_2");
  196. })
  197. .delay(fastDelayTime - delayPlaySoundTime)
  198. .call(()=>{
  199. this.rollBgisStop[i] = true;
  200. this.isFastStop = i == 5;
  201. })
  202. .start();
  203. return;
  204. } else {
  205. //
  206. }
  207. }
  208. // 都停止了就展示结果
  209. if(i > 5) {
  210. this.isFast = false;
  211. this.isScroll = false;
  212. this.rollSpine.active = false;
  213. let delayTime = 200;
  214. this.delayShowPrizes(delayTime);
  215. return;
  216. }
  217. let isAppearScatter = false;
  218. //先统计Scatter数量
  219. for(let j = 0; j < GameConstant.MAX_ROW; ++j) {
  220. if(this.resultValues[i][j] == GameConstant.SPECIAL_ICON) {
  221. this.freeIconCount++;
  222. isAppearScatter = true;
  223. }
  224. }
  225. // 现逻辑
  226. let resultRollbg = this.resultRollNodes[i];
  227. let destY = 0;
  228. // 修改当前列结果展示图标
  229. for (let j = 0; j < GameConstant.MAX_ROW; j++) {
  230. this.rollNodeIcons[i][4 + j].getComponent(Item).setIconType(this.resultValues[i][j], false);
  231. this.resultRollIcons[i][4 + j].getComponent(Item).setIconType(this.resultValues[i][j], true, this.resultWildTimes[i][j]);
  232. this.resultIcons[i][j].getComponent(Item).setIconType(this.resultValues[i][j], true, this.resultWildTimes[i][j]);
  233. }
  234. this.resultRollIcons[i][3].getComponent(Item).setIconType(this.resultRollIcons[i][3].getComponent(Item).getIconType(), true);
  235. this.resultRollIcons[i][8].getComponent(Item).setIconType(this.resultRollIcons[i][8].getComponent(Item).getIconType(), true);
  236. var downTime = this.isFast ? 1.0 : 1.2;
  237. var upTime = this.isFast ? 0.15 : 0.1;
  238. // 滚动层正常停止动作
  239. tween(resultRollbg)
  240. .call(()=>{
  241. if (i + 1 <= 5) {
  242. this.rollBgisStop[i + 1] = true;
  243. }
  244. })
  245. .to(downTime, {y: destY - 40}, {easing: 'sineOut'})//, {easing: 'sineIn'}
  246. .call(()=>{
  247. })
  248. .to(upTime, {y: destY})//, {easing: 'sineOut'}
  249. .call(()=>{
  250. })
  251. .delay(0.1)
  252. .call(()=>{
  253. this.rollBgisStop[i] = false;
  254. this.showResultIcons(i);
  255. if (i == 5) {
  256. // console.log("end rollEnds i = " + i)
  257. this.rollEnds(i + 1);
  258. }
  259. })
  260. .start();
  261. let rollbg = this.rollNodes[i]
  262. let dest = -2220;
  263. // 相同滚动层一起位移
  264. tween(rollbg)
  265. .to(downTime, {y: dest}, {easing: 'sineOut'})
  266. .delay(0.5)
  267. .call(()=>{
  268. this.rollNodes[i].active = true;
  269. this.rollNodes[i].y = 2220;
  270. })
  271. .start();
  272. }
  273. // 快速停止列
  274. justEnd(i) {
  275. if(i >= GameConstant.MAX_COL) {
  276. return;
  277. }
  278. let resultRollbg = this.resultRollNodes[i];
  279. Tween.stopAllByTarget(resultRollbg);
  280. resultRollbg.y = 0;//270
  281. Tween.stopAllByTarget(this.rollNodes[i]);
  282. this.rollNodes[i].y = 2220;
  283. let destY = 0;
  284. for (let j = 0; j < GameConstant.MAX_ROW; j++) {
  285. this.rollNodeIcons[i][4 + j].getComponent(Item).setIconType(this.resultValues[i][j], false);
  286. this.resultRollIcons[i][4 + j].getComponent(Item).setIconType(this.resultValues[i][j], true, this.resultWildTimes[i][j]);
  287. this.resultIcons[i][j].getComponent(Item).setIconType(this.resultValues[i][j], true, this.resultWildTimes[i][j]);
  288. }
  289. this.resultRollIcons[i][3].getComponent(Item).setIconType(this.resultRollIcons[i][3].getComponent(Item).getIconType(), true);
  290. this.resultRollIcons[i][8].getComponent(Item).setIconType(this.resultRollIcons[i][8].getComponent(Item).getIconType(), true);
  291. // 滚动层正常停止动作
  292. tween(resultRollbg)
  293. .to(0.2, {y: destY - 40})//, {easing: 'sineIn'}
  294. .to(0.05, {y: destY})//, {easing: 'sineOut'}
  295. .call(()=>{
  296. this.showResultIcons(i);
  297. })
  298. .start();
  299. }
  300. // 转动逻辑
  301. update(deltaTime: number) {
  302. if (!this.isScroll)
  303. return;
  304. for (let i = 0; i < GameConstant.MAX_COL; i++)
  305. {
  306. if (this.rollBgIsScroll[i]) {
  307. var interval = this.isFast ? GameConstant.ROLL_FAST_SPEED : GameConstant.ROLL_NORMAL_SPEED;
  308. this.rollNodes[i].y -= deltaTime * interval;
  309. this.resultRollNodes[i].y -= deltaTime * interval;
  310. if (this.rollNodes[i].y <= -2400) {
  311. this.rollNodes[i].y = this.resultRollNodes[i].y + this.rollNodes[i].getComponent(UITransform).height;
  312. }
  313. if (this.resultRollNodes[i].y <= -2400) {
  314. this.resultRollNodes[i].y = this.rollNodes[i].y + this.resultRollNodes[i].getComponent(UITransform).height;
  315. if (this.rollBgisStop[i]) {
  316. this.rollBgIsScroll[i] = false;
  317. this.rollBgisStop[i] = false;
  318. this.rollEnds(i);
  319. }
  320. }
  321. }
  322. }
  323. }
  324. // 接收到结果数据之后设置客户端的结果数据
  325. setRollDatas(msg, bSpecialGame) {
  326. this.rollResultData = msg;
  327. for (let i = 0; i < GameConstant.MAX_ROW; i++) {
  328. for (let j = 0; j < GameConstant.MAX_COL; j++) {
  329. this.resultValues[j][i] = this.rollResultData.m_desk_data[i][j];
  330. this.resultWildTimes[j][i] = this.rollResultData.m_wildTimes_data[i][j];
  331. }
  332. }
  333. this.hasSpecial = this.rollResultData.m_isSpecialGame == 1;
  334. // console.log(this.resultValues);
  335. }
  336. // 展示结果函数
  337. openPrizes(justEnd, bQuick) {
  338. if(this.bGameEnd == true) {
  339. return;
  340. }
  341. let endTime = new Date().getTime();
  342. let leftTime = 0;//this._startRollTime - endTime + 500;
  343. this.delayTime = 0.2;
  344. if(justEnd) {
  345. this.delayTime = 0;
  346. }
  347. Tween.stopAllByTarget(this.node);
  348. this.bQuick = bQuick;
  349. this.freeIconCount = 0;
  350. //快速,并且前四排免费图标总数少于2
  351. if(justEnd) {
  352. // this.playEffect("skip");
  353. for(let i = 0; i < GameConstant.MAX_COL; ++i) {
  354. if (i == 0) this.isScroll = false;
  355. this.rollBgIsScroll[i] = false;
  356. this.rollBgisStop[i] = false;
  357. this.justEnd(i);
  358. if(i >= 5) {
  359. this.delayShowPrizes(200);
  360. }
  361. }
  362. return;
  363. }
  364. tween(this.node)
  365. .delay(leftTime/1000)
  366. .call(()=>{
  367. this.rollBgisStop[0] = true;
  368. })
  369. .start()
  370. }
  371. // 转动结束之后的最终函数
  372. delayShowPrizes(delayTime) {
  373. let extraDelayTime = 0.5
  374. if(this.rollResultData.m_isSpecialGame == 1) {
  375. extraDelayTime = 2.2
  376. }
  377. // for (let i = 0; i < GameConstant.MAX_COL; i++) {
  378. // console.log("delayShowPrizes this.rollBG[i].y = " + this.rollNodes[i].y + ", this.resultRollBg[i].y = " + this.resultRollNodes[i].y);
  379. // }
  380. tween(this.node)
  381. .delay(delayTime / 1000)
  382. .call(()=>{
  383. // this.beforeShowPrize();
  384. })
  385. .delay(0.3)
  386. .call(()=>{
  387. if (this.hasSpecial){
  388. this.showPrizes();
  389. this.showSpecialPrize();
  390. this.node.parent.getComponent(GameScene).showGameWinScore();
  391. } else {
  392. this.bGameEnd = true;
  393. this.showPrizes();
  394. this.node.parent.getComponent(GameScene).showGameWinScore();
  395. }
  396. })
  397. .delay(extraDelayTime)
  398. .call(()=>{
  399. this.node.parent.getComponent(GameScene).showGameEnd();
  400. })
  401. .start()
  402. }
  403. // beforeShowPrize() {
  404. // for(let i = 0; i < GameConstant.MAX_COL; ++i) {
  405. // for(let j = 0; j < GameConstant.MAX_ROW; ++j) {
  406. // if (this.resultIcons[i][j].getComponent(Item).getIconType() == GameConstant.SPECIAL_ICON)
  407. // continue;
  408. // this.resultIcons[i][j].getComponent(Item).showNormal();
  409. // }
  410. // }
  411. // }
  412. // 展示图标动画
  413. showPrizes() {
  414. for(let i = 0; i < GameConstant.MAX_COL; ++i) {
  415. for(let j = 0; j < GameConstant.MAX_ROW; ++j) {
  416. if (this.rollResultData.m_line_icon_active[j][i] > 0) {
  417. this.resultIcons[i][j].getComponent(Item).showLightAni();
  418. }
  419. }
  420. }
  421. if (this.rollResultData.m_line_size.length > 0) {
  422. tween(this.node)
  423. .delay(2.5)
  424. .call(()=>{
  425. this.showLines(0);
  426. })
  427. .start();
  428. }
  429. }
  430. // 每条线的动画展示和下面的中奖细节展示
  431. showLines(iIndex) {
  432. if(iIndex >= this.rollResultData.m_line_index.length) {
  433. this.showPrizes();
  434. return;
  435. }
  436. this.winDetail.active = !this.isInScatterGame;
  437. this.showWinDetail(iIndex);
  438. let count = this.rollResultData.m_line_index[iIndex];
  439. for (let i = 0; i < this.rollResultData.m_line_index[iIndex].length; i++) {
  440. var x = Math.floor(this.rollResultData.m_line_index[iIndex][i] / GameConstant.MAX_COL);
  441. var y = this.rollResultData.m_line_index[iIndex][i] % GameConstant.MAX_COL;
  442. this.resultIcons[y][x].getComponent(Item).showLightAni();
  443. }
  444. tween(this.node)
  445. .delay(2)
  446. .call(()=>{
  447. this.showLines(iIndex + 1);
  448. })
  449. .start();
  450. }
  451. // 展示中奖细节
  452. showWinDetail(iIndex) {
  453. let isPlaying = false;
  454. this.winDetailIcons.removeAllChildren();
  455. let iconWidth = 0;
  456. let normalIconW = 0;
  457. let leftIndex = this.rollResultData.m_line_icon[iIndex].length / 2;
  458. for(let k = 0; k < this.rollResultData.m_line_icon[iIndex].length; ++k) {
  459. let resultType = this.rollResultData.m_line_icon[iIndex][k];
  460. let icon = instantiate(this.item);
  461. var x = Math.floor(this.rollResultData.m_line_index[iIndex][k] / GameConstant.MAX_COL);
  462. var y = this.rollResultData.m_line_index[iIndex][k] % GameConstant.MAX_COL;
  463. icon.getComponent(Item).setIconType(resultType, true , this.resultWildTimes[y][x]);
  464. icon.scale = new Vec3(0.15, 0.15, 0.15);
  465. icon.parent = this.winDetailIcons;
  466. icon.active = true;
  467. normalIconW = (icon.getComponent(UITransform).width + 0) * icon.scale.x + 10;
  468. icon.x = normalIconW * (-(leftIndex - k) + 0.5) + 0;
  469. iconWidth += normalIconW;
  470. }
  471. this.winDetailLabel.x = iconWidth / 2;
  472. let singleLineBet = this.node.parent.getComponent(GameScene).getSingleLineBet();
  473. let score = this.rollResultData.m_line_times[iIndex] * singleLineBet;
  474. let str = GameConstant.formatNumber(score);
  475. this.winDetailLabel.getComponent(Label).string = str;
  476. this.winDetailLabel.getComponent(Label).updateRenderData(true);
  477. this.winDetail.getComponent(UIOpacity).opacity = 0;
  478. tween(this.winDetail.getComponent(UIOpacity))
  479. .call(()=>{
  480. let interval = (-this.winDetailLabel.getComponent(UITransform).width) / 2;
  481. this.winDetailIcons.x = interval;
  482. this.winDetailLabel.x = this.winDetailIcons.x + iconWidth / 2;
  483. })
  484. .to(0.3, {opacity: 255})
  485. .delay(1.5)
  486. .to(0.3, {opacity: 0})
  487. .start()
  488. }
  489. // 展示特殊图标
  490. showSpecialPrize() {
  491. console.log("showSpecialPrize");
  492. for(let i = 0; i < GameConstant.MAX_COL; ++i) {
  493. for(let j = 0; j < GameConstant.MAX_ROW; ++j) {
  494. this.resultIcons[i][j].getComponent(Item).showSpecialAni();
  495. }
  496. }
  497. }
  498. }