GridView.js 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327
  1. import {
  2. CELL_HEIGHT,
  3. CELL_WIDTH,
  4. GRID_HEIGHT,
  5. GRID_PIXEL_HEIGHT,
  6. GRID_PIXEL_WIDTH,
  7. GRID_WIDTH
  8. } from "../Model/ConstValue";
  9. import AudioUtils from "../Utils/AudioUtils";
  10. import GameModel from "../Model/GameModel";
  11. cc.Class({
  12. extends: cc.Component,
  13. properties: {
  14. aniPre:{
  15. default:[],
  16. type:[cc.Prefab]
  17. },
  18. effectLayer:{
  19. default: null,
  20. type: cc.Node
  21. },
  22. audioUtils:{
  23. default:null,
  24. type:AudioUtils
  25. }
  26. },
  27. // LIFE-CYCLE CALLBACKS:
  28. onLoad () {
  29. this.setListener();
  30. this.lastTouchPos = cc.Vec2(-1,-1);
  31. this.isCanMove = true;
  32. this.isInPlayAni = false; //是否在播放中
  33. // let gNode = cc.find("Canvas/GameScene/Grid")
  34. // console.log("this.node:",this.node)
  35. this.node.width = GRID_WIDTH * CELL_WIDTH;
  36. this.node.height = GRID_HEIGHT * CELL_HEIGHT;
  37. // console.log("gNode:",gNode)
  38. },
  39. setController(controller){
  40. this.controller = controller;
  41. },
  42. initWithCellModels(cellsModels){
  43. // console.log("cellsModels:",cellsModels)
  44. this.cellViews = [];
  45. for (let i = 1; i <= GRID_HEIGHT; i++){ //行,y
  46. this.cellViews[i] = [];
  47. for (let j = 1; j <= GRID_WIDTH; j++){ //列,x
  48. let type = cellsModels[i][j].type;
  49. // console.log(`cellsModels[${i}][${j}]:`,cellsModels[i][j])
  50. let aniView = cc.instantiate(this.aniPre[type]);
  51. aniView.parent = this.node;
  52. let cellViewScript = aniView.getComponent("CellView");
  53. cellViewScript.initWithModel(cellsModels[i][j]);
  54. this.cellViews[i][j] = aniView;
  55. }
  56. }
  57. },
  58. setListener(){
  59. this.node.on(cc.Node.EventType.TOUCH_START,function (eventTouch) {
  60. if (this.isInPlayAni){ //播放动画中,不允许点击
  61. return true;
  62. }
  63. let touchPos = eventTouch.getLocation();
  64. let cellPos = this.convertTouchPosToCell(touchPos);
  65. // 消除一个格子的技能
  66. if(this.controller.isCrushOne){
  67. this.controller.isCrushOne = false;
  68. this.controller.eliminateOneNum--;
  69. this.controller.showSkillTip(false);
  70. const result = this.controller.processCrushOne(cellPos);
  71. // console.log("cellpos:",cellPos)
  72. // console.log("消除一个格子result:",result)
  73. let changeModels = result[0]; // 有改变的cell
  74. let effectsQueue = result[1]; //各种特效
  75. this.playEffect(effectsQueue);
  76. this.disableTouch(this.getPlayAniTime(changeModels), this.getStep(effectsQueue));
  77. this.updateView(changeModels);
  78. this.controller.cleanCmd();
  79. // console.log("rerr:",result)
  80. return false;
  81. }
  82. //道具消除整行
  83. if (this.controller.isCrushRow){
  84. this.controller.isCrushRow = false;
  85. // console.log("crushRowAllNum:",this.controller.crushRowAllNum)
  86. this.controller.crushRowAllNum--;
  87. this.controller.showSkillTip(false);
  88. const crushRowResult = this.controller.processCrushRow(cellPos);
  89. // console.log("消除一行的pos:",cellPos)
  90. // console.log("crushRowResult:",crushRowResult)
  91. let changeModels = crushRowResult[0];
  92. let effectsQueue = crushRowResult[1]; //各种特效
  93. this.playEffect(effectsQueue);
  94. this.disableTouch(this.getPlayAniTime(changeModels), this.getStep(effectsQueue));
  95. this.updateView(changeModels);
  96. this.controller.cleanCmd();
  97. return false;
  98. }
  99. //道具消除整列
  100. if (this.controller.isCrushCol){
  101. this.audioUtils.playClick();
  102. this.controller.isCrushCol = false;
  103. this.controller.crushColAllNum--;
  104. this.controller.showSkillTip(false);
  105. const crushColResult = this.controller.processCrushCol(cellPos);
  106. let changeModels = crushColResult[0];
  107. let effectsQueue = crushColResult[1]; //各种特效
  108. this.playEffect(effectsQueue);
  109. this.disableTouch(this.getPlayAniTime(changeModels), this.getStep(effectsQueue));
  110. this.updateView(changeModels);
  111. this.controller.cleanCmd();
  112. return false;
  113. }
  114. //道具消除一种类型
  115. if (this.controller.isCrushOneType){
  116. this.audioUtils.playClick();
  117. this.controller.isCrushOneType = false;
  118. this.controller.crushOneTypeNum--;
  119. this.controller.showSkillTip(false);
  120. const crushOneTypeResult = this.controller.processCrushOneType(cellPos);
  121. // console.log("crushOneTypeResult:",crushOneTypeResult)
  122. let changeModels = crushOneTypeResult[0];
  123. let effectsQueue = crushOneTypeResult[1]; //各种特效
  124. this.playEffect(effectsQueue);
  125. this.disableTouch(this.getPlayAniTime(changeModels), this.getStep(effectsQueue));
  126. this.updateView(changeModels);
  127. this.controller.cleanCmd();
  128. return false;
  129. }
  130. if (cellPos){
  131. let changeModels = this.selectCell(cellPos);
  132. this.isCanMove = changeModels.length < 3;
  133. }else {
  134. this.isCanMove = false;
  135. }
  136. return true;
  137. },this);
  138. //滑动操作逻辑
  139. this.node.on(cc.Node.EventType.TOUCH_MOVE,function (eventTouch) {
  140. if (this.isCanMove){
  141. let startTouchPos = eventTouch.getStartLocation();
  142. let startCellPos = this.convertTouchPosToCell(startTouchPos);
  143. let touchPos = eventTouch.getLocation();
  144. let cellPos = this.convertTouchPosToCell(touchPos);
  145. if (startCellPos.x != cellPos.x || startCellPos.y != cellPos.y){
  146. this.isCanMove = false;
  147. let changeModels = this.selectCell(cellPos);
  148. // console.log("changeModels:",changeModels)
  149. }
  150. }
  151. },this);
  152. this.node.on(cc.Node.EventType.TOUCH_END, function (eventTouch) {
  153. // console.log("1111");
  154. },this);
  155. this.node.on(cc.Node.EventType.TOUCH_CANCEL,function (eventTouch) {
  156. // console.log("2222");
  157. },this);
  158. },
  159. //根据点击的像素位置,转换成网格中的位置
  160. convertTouchPosToCell(pos){
  161. pos = this.node.convertToNodeSpaceAR(pos);
  162. if (pos.x < 0 || pos.x >= GRID_PIXEL_WIDTH || pos.y < 0 || pos.y >= GRID_PIXEL_HEIGHT){
  163. return false;
  164. }
  165. let x = Math.floor(pos.x / CELL_WIDTH) + 1;
  166. let y = Math.floor(pos.y / CELL_HEIGHT) + 1;
  167. return cc.v2(x, y);
  168. },
  169. //移动格子
  170. updateView(changeModels){
  171. let newCellViewInfo = [];
  172. for (let i in changeModels){
  173. let model = changeModels[i];
  174. let viewInfo = this.findViewByModel(model);
  175. let view = null;
  176. if (!viewInfo){ //如果原来的cell不存在,则新建
  177. let type = model.type;
  178. let aniView = cc.instantiate(this.aniPre[type]);
  179. aniView.parent = this.node;
  180. let cellViewScript = aniView.getComponent("CellView");
  181. cellViewScript.initWithModel(model);
  182. view = aniView;
  183. }else { //如果已经存在
  184. view = viewInfo.view;
  185. this.cellViews[viewInfo.y][viewInfo.x] = null;
  186. }
  187. let cellScript = view.getComponent("CellView");
  188. cellScript.updateView(); //执行移动动作
  189. if (!model.isDeath){
  190. newCellViewInfo.push({
  191. model: model,
  192. view: view
  193. });
  194. }
  195. }
  196. //重新标记this.cellViews的信息
  197. newCellViewInfo.forEach(function (ele) {
  198. let model = ele.model;
  199. this.cellViews[model.y][model.x] = ele.view;
  200. },this);
  201. },
  202. //显示选中的格子背景
  203. updateSelect(pos){
  204. for (let i = 1; i <= GRID_HEIGHT; i++){ //行,y值
  205. for (let j = 1; j <= GRID_WIDTH; j++){ //列,x值
  206. // console.log(`选中的格子:cellViews[${i}][${j}]:`,this.cellViews[i][j])
  207. if (this.cellViews[i][j]){
  208. let cellScript = this.cellViews[i][j].getComponent("CellView");
  209. // console.log("cellScript:",cellScript)
  210. if (pos.x == j && pos.y == i){
  211. cellScript.setSelect(true);
  212. // console.log("选中了")
  213. }else {
  214. cellScript.setSelect(false);
  215. }
  216. }
  217. }
  218. }
  219. },
  220. //根据cell的model返回对应的View
  221. findViewByModel(model){
  222. // console.log("model:",model);
  223. for (let i = 1; i <= GRID_HEIGHT; i++){ //行,y值
  224. for (let j = 1; j <= GRID_WIDTH; j++){ //列,x值
  225. // console.log(`cellViews[${i}][${j}]:`,this.cellViews[i][j]); //此处打印会出现死循环
  226. if (this.cellViews[i][j] && this.cellViews[i][j].getComponent("CellView").model == model){
  227. return {view:this.cellViews[i][j], x:j, y:i};
  228. }
  229. }
  230. }
  231. return null;
  232. },
  233. getPlayAniTime(changeModels){
  234. if (!changeModels){
  235. return 0;
  236. }
  237. let maxTime = 0;
  238. changeModels.forEach(function (ele) {
  239. ele.cmd.forEach(function (cmd) {
  240. if (maxTime < cmd.playTime + cmd.keepTime){
  241. maxTime = cmd.playTime + cmd.keepTime;
  242. }
  243. },this)
  244. },this);
  245. return maxTime;
  246. },
  247. //获得爆炸次数,同一个时间算一个
  248. getStep(effectsQueue){
  249. if (!effectsQueue){
  250. return 0;
  251. }
  252. return effectsQueue.reduce(function (maxValue, effectCmd) {
  253. return Math.max(maxValue, effectCmd.step || 0);
  254. },0);
  255. },
  256. //一段时间内禁止操作
  257. disableTouch(time, step){
  258. if (time <= 0){
  259. return;
  260. }
  261. this.isInPlayAni = true;
  262. this.node.runAction(cc.sequence(cc.delayTime(time),cc.callFunc(function (){
  263. this.isInPlayAni = false;
  264. this.audioUtils.playContinuousMatch(step);
  265. },this)));
  266. },
  267. //正常击中格子后的操作
  268. selectCell(cellPos){
  269. let result = this.controller.selectCell(cellPos); //直接先丢给model处理数据逻辑
  270. // console.log("result:",result);
  271. let changeModels = result[0]; //有改变的cell,包含新生成的cell和生成马上摧毁的格子
  272. let effectsQueue = result[1]; //各种特效
  273. this.playEffect(effectsQueue);
  274. this.disableTouch(this.getPlayAniTime(changeModels),this.getStep(effectsQueue));
  275. this.updateView(changeModels);
  276. this.controller.cleanCmd();
  277. if (changeModels.length >= 2){
  278. this.updateSelect(cc.v2(-1, -1));
  279. this.audioUtils.playSwap();
  280. }else {
  281. this.updateSelect(cellPos);
  282. this.audioUtils.playClick();
  283. }
  284. return changeModels;
  285. },
  286. playEffect(effectsQueue){
  287. this.effectLayer.getComponent("EffectLayer").playEffects(effectsQueue, this.controller);
  288. },
  289. start () {
  290. },
  291. // update (dt) {},
  292. });