GridView.js 12 KB

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