GameModel.js 32 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887
  1. import CellModel from "./CellModel";
  2. import {mergePointArray,exclusivePoint} from "../Utils/ModelUtils";
  3. import {ANITIME, CELL_BASENUM, CELL_STATUS, CELL_TYPE, GRID_HEIGHT, GRID_WIDTH} from "./ConstValue";
  4. export default class GameModel {
  5. constructor() {
  6. this.cells = null;
  7. this.cellBgs = null;
  8. this.lastPos = cc.v2(-1,-1);
  9. this.cellTypeNum = 5;
  10. this.cellCreateType = []; //生成种类只在这个数组里面查找
  11. this.crushNums = 0; //消除的块数
  12. // this.curGridPos = {};
  13. // this.targetOneTypeNum = 0;
  14. // this.targetTwoTypeNum = 0;
  15. // this.targetThreeTypeNum = 0;
  16. }
  17. init(cellTypeNum){
  18. this.gridView = cc.find("Canvas/GameScene/Grid").getComponent("GridView")
  19. // console.log("gridView.width:",this.gridView.grid_width)
  20. this.cells = [];
  21. this.setCellTypeNum(cellTypeNum || this.cellTypeNum);
  22. for (let i = 1; i <= this.gridView.grid_width; i++){
  23. this.cells[i] = [];
  24. for (let j = 1; j <= this.gridView.grid_height; j++){
  25. this.cells[i][j] = new CellModel()
  26. }
  27. }
  28. //this.mock()
  29. for (let i = 1; i <= this.gridView.grid_width; i++){
  30. for (let j = 1; j <= this.gridView.grid_height; j++){
  31. //已经被mock数据生成了
  32. if (this.cells[i][j].type != null){
  33. continue;
  34. }
  35. let flag = true;
  36. while (flag){
  37. flag = false;
  38. this.cells[i][j].init(this.getRandomCellType());
  39. let result = this.checkPoint(j, i)[0];
  40. if (result.length > 2){
  41. flag = true;
  42. }
  43. this.cells[i][j].setXY(j, i);
  44. this.cells[i][j].setStartXY(j, i);
  45. }
  46. }
  47. }
  48. }
  49. mock(){
  50. this.mockInit(5,1,CELL_TYPE.A);
  51. this.mockInit(5,3,CELL_TYPE.A);
  52. this.mockInit(4,2,CELL_TYPE.A);
  53. this.mockInit(3,2,CELL_TYPE.A);
  54. this.mockInit(5,2,CELL_TYPE.B);
  55. this.mockInit(6,2,CELL_TYPE.B);
  56. this.mockInit(7,3,CELL_TYPE.B);
  57. this.mockInit(8,2,CELL_TYPE.A);
  58. // this.mockInit(1, 1, CELL_TYPE.A);
  59. // this.mockInit(1, 2, CELL_TYPE.A);
  60. // this.mockInit(1, 3, CELL_TYPE.A);
  61. // this.mockInit(1, 5, CELL_TYPE.A);
  62. // this.mockInit(2, 1, CELL_TYPE.B);
  63. // this.mockInit(2, 2, CELL_TYPE.B);
  64. // this.mockInit(2, 3, CELL_TYPE.B);
  65. // this.mockInit(2, 5, CELL_TYPE.B);
  66. // this.mockInit(3, 4, CELL_TYPE.A);
  67. // this.mockInit(4, 4, CELL_TYPE.A);
  68. // console.log("mock")
  69. }
  70. mockInit(x, y, type){
  71. this.cells[x][y].init(type);
  72. this.cells[x][y].setXY(y, x);
  73. this.cells[x][y].setStartXY(y, x);
  74. }
  75. /**
  76. *
  77. * @param x
  78. * @param y
  79. * @param recursive 是否递归查找
  80. * @returns {([]|string|*)[]}
  81. */
  82. checkPoint(x, y, recursive){
  83. // console.log("递归了x",x)
  84. // console.log("递归了y",y)
  85. let rowResult = this.checkWithDirection(x, y, [cc.v2(1,0),cc.v2(-1,0)]);
  86. let colResult = this.checkWithDirection(x, y, [cc.v2(0,-1),cc.v2(0,1)]);
  87. let samePoints = [];
  88. let newCellStatus = "";
  89. if (rowResult.length >= 5 || colResult.length >= 5){
  90. //任意五个'同行'或'同列'且相同的动物可以合成一个'魔力鸟'特效
  91. newCellStatus = CELL_STATUS.BIRD;
  92. }else if (rowResult.length >= 3 && colResult.length >= 3){
  93. //五个相同的'不同行'动物可以合成一个'爆炸特效'
  94. newCellStatus = CELL_STATUS.WRAP;
  95. }else if (rowResult.length >= 4){
  96. //四个相同的动物一行可以合成一个行直线特效
  97. newCellStatus = CELL_STATUS.LINE;
  98. }else if (colResult.length >= 4){
  99. //四个相同的动物一列可以合成一个列直线特效
  100. newCellStatus = CELL_STATUS.COLUMN;
  101. }
  102. if (rowResult.length >= 3){
  103. samePoints = rowResult;
  104. }
  105. if (colResult.length >= 3){
  106. samePoints = mergePointArray(samePoints, colResult);
  107. }
  108. let result = [samePoints, newCellStatus, this.cells[y][x].type, cc.v2(x, y)];
  109. //检查一下消除的其他节点, 能不能生成更大范围的消除
  110. if (recursive && result.length >= 3){
  111. let subCheckPoints = exclusivePoint(samePoints, cc.v2(x, y));
  112. for (let point of subCheckPoints){
  113. let subResult = this.checkPoint(point.x, point.y, false);
  114. if (subResult[1] > result[1] || (subResult[1] === result[1] && subResult[0].length > result[0].length)){
  115. result = subResult;
  116. }
  117. }
  118. }
  119. return result;
  120. }
  121. checkWithDirection(x, y, direction){
  122. //x是行,y是列
  123. let queue = [];
  124. let vis = [];
  125. vis[x + y * this.gridView.grid_height] = true; //9是行
  126. queue.push(cc.v2(x, y)); //x是行,y是列,生成的队列是按列从左往右
  127. let front = 0;
  128. while (front < queue.length){
  129. let point = queue[front];
  130. let cellModel = this.cells[point.y][point.x]; //point.y是行,point.x是列
  131. // console.log(`this.cells[point.${y}][point.${x}]:`,this.cells[point.y][point.x])
  132. front++;
  133. if (!cellModel){
  134. continue;
  135. }
  136. for (let i = 0; i < direction.length; i++){
  137. let tmpX = point.x + direction[i].x;
  138. let tmpY = point.y + direction[i].y;
  139. // console.log(`tmpX[${i}]:`,tmpX)
  140. // console.log(`tmpY[${i}]:`,tmpY)
  141. if (tmpX < 1 || tmpX > this.gridView.grid_width //9是行
  142. || tmpY < 1 || tmpY > this.gridView.grid_height
  143. || vis[tmpX + tmpY * this.gridView.grid_height]
  144. || !this.cells[tmpY][tmpX]){
  145. continue;
  146. }
  147. // console.log(`this.cells[${tmpY}][${tmpX}]`,this.cells[tmpY][tmpX])
  148. if (cellModel.type === this.cells[tmpY][tmpX].type){
  149. vis[tmpX + tmpY * this.gridView.grid_height] = true;
  150. queue.push(cc.v2(tmpX, tmpY));
  151. // console.log("cc.v2(tmpX, tmpY):",cc.v2(tmpX, tmpY))
  152. }
  153. }
  154. }
  155. return queue;
  156. }
  157. printInfo(){
  158. // console.log("gridView.width2:",this.gridView.grid_width)
  159. for (let i = 1; i <= this.gridView.grid_height; i++){
  160. let printStr = "";
  161. for (let j = 1; j <= this.gridView.grid_width; j++){
  162. printStr += this.cells[i][j].type + " ";
  163. }
  164. console.log("printStr:",printStr);
  165. }
  166. }
  167. getCells(){
  168. return this.cells;
  169. }
  170. //controller调用的主要入口
  171. //点击某个格子
  172. selectCell(pos){
  173. this.crushNums = 0;
  174. // this.targetOneTypeNum = 0;
  175. // this.targetTwoTypeNum = 0;
  176. // this.targetThreeTypeNum = 0;
  177. // console.log("当前点击的位置:",pos);
  178. // this.curGridPos = pos;
  179. // console.log("当前点击对象:",this.curGridPos)
  180. this.changeModels = []; //发生改变的model,将作为返回值,给View播动作
  181. this.effectsQueue = []; //动物消失、爆炸等特效
  182. let lastPos = this.lastPos;
  183. let delta = Math.abs(pos.x - lastPos.x) + Math.abs(pos.y - lastPos.y);
  184. // console.log("x轴:",Math.abs(pos.x - lastPos.x))
  185. // console.log("y轴:",Math.abs(pos.y - lastPos.y))
  186. // console.log("delta:",delta)
  187. if (delta != 1){ //非相邻格子,直接返回
  188. this.lastPos = pos;
  189. return [[], []];
  190. }
  191. let curClickCell = this.cells[pos.y][pos.x]; //当前点击的格子
  192. let lastClickCell = this.cells[lastPos.y][lastPos.x]; //上一次点击的格子
  193. this.exchangeCell(lastPos, pos);
  194. let result1 = this.checkPoint(pos.x, pos.y)[0];
  195. let result2 = this.checkPoint(lastPos.x, lastPos.y)[0];
  196. this.curTime = 0; //动画播放的当前时间
  197. this.pushToChangeModels(curClickCell);
  198. this.pushToChangeModels(lastClickCell);
  199. let isCanBomb = (curClickCell.status != CELL_STATUS.COMMON && //判断两个是否是特殊的动物
  200. lastClickCell.status != CELL_STATUS.COMMON) ||
  201. curClickCell.status == CELL_STATUS.BIRD ||
  202. lastClickCell.status == CELL_STATUS.BIRD;
  203. isCanBomb = curClickCell.status == CELL_STATUS.BIRD || lastClickCell.status == CELL_STATUS.BIRD;
  204. if (result1.length < 3 && result2.length < 3 && !isCanBomb){ //不会发生消除的情况
  205. this.exchangeCell(lastPos, pos);
  206. curClickCell.moveToAndBack(lastPos);
  207. lastClickCell.moveToAndBack(pos);
  208. this.lastPos = cc.v2(-1,-1);
  209. return [this.changeModels];
  210. }else {
  211. // console.log("消除了")
  212. this.lastPos = cc.v2(-1,-1);
  213. curClickCell.moveTo(lastPos, this.curTime);
  214. lastClickCell.moveTo(pos, this.curTime);
  215. let checkPoint = [pos, lastPos];
  216. // console.log("select的checkpoint:",checkPoint)
  217. this.curTime += ANITIME.TOUCH_MOVE;
  218. this.processCrush(checkPoint);
  219. return [this.changeModels,this.effectsQueue];
  220. }
  221. }
  222. //消除
  223. processCrush(checkPoint){
  224. // console.log("消除checkpoint:",checkPoint)
  225. let cycleCount = 0;
  226. while (checkPoint.length > 0){
  227. let bombModels = [];
  228. if (cycleCount == 0 && checkPoint.length == 2){ //特殊消除
  229. let pos1 = checkPoint[0];
  230. let pos2 = checkPoint[1];
  231. let model1 = this.cells[pos1.y][pos1.x];
  232. let model2 = this.cells[pos2.y][pos2.x];
  233. if (model1.status == CELL_STATUS.BIRD || model2.status == CELL_STATUS.BIRD){
  234. let bombModel = null;
  235. if (model1.status == CELL_STATUS.BIRD){
  236. model1.type = model2.type;
  237. bombModels.push(model1);
  238. }else {
  239. model2.type = model1.type;
  240. bombModels.push(model2);
  241. }
  242. }
  243. }
  244. for (let i in checkPoint){
  245. let pos = checkPoint[i];
  246. // console.log("消除中的pos:",pos)
  247. if (!this.cells[pos.y][pos.x]){
  248. continue;
  249. }
  250. let [result, newCellStatus, newCellType, crushPoint] = this.checkPoint(pos.x,pos.y,true);
  251. // console.log("result:",result)
  252. if (result.length < 3){
  253. continue;
  254. }
  255. for (let j in result){
  256. // console.log("result[" + j +"]:",result[j])
  257. let model = this.cells[result[j].y][result[j].x];
  258. this.crushCell(result[j].x, result[j].y,false, cycleCount);
  259. if (model.status != CELL_STATUS.COMMON){
  260. bombModels.push(model);
  261. }
  262. }
  263. this.createNewCell(crushPoint, newCellStatus, newCellType);
  264. // if (result.length >= 3){
  265. // for (let i = 0; i < result.length; i++){
  266. // console.log("result[" + i +"]:",result[i])
  267. // }
  268. // }
  269. }
  270. this.processBomb(bombModels,cycleCount);
  271. this.curTime += ANITIME.DIE;
  272. checkPoint = this.down();
  273. // console.log("cccheckPoint:",checkPoint)
  274. // console.log("this.down:",this.down())
  275. cycleCount++;
  276. }
  277. // console.log("消除块数:",this.crushNums)
  278. // console.log("bear:",this.targetOneTypeNum)
  279. const playTime = this.effectsQueue[this.effectsQueue.length - 1]["playTime"]
  280. // console.log("playTime:",playTime)
  281. //按类型消除
  282. // this.addCrushNums(playTime,cc.v2(0,0),this.crushNums,this.targetOneTypeNum,this.targetTwoTypeNum,this.targetThreeTypeNum);
  283. //不按类型消除
  284. this.addCrushNums(playTime,cc.v2(0,0),this.crushNums);
  285. }
  286. //道具消除一个块
  287. processCrushOne(pos){
  288. // console.log("gridView.width3:",this.gridView.grid_width)
  289. // console.log("gmpos:",pos)
  290. this.changeModels = [];
  291. this.effectsQueue = [];
  292. this.curTime = 0;
  293. this.crushNums = 0;
  294. // this.targetOneTypeNum = 0;
  295. // this.targetTwoTypeNum = 0;
  296. // this.targetThreeTypeNum = 0;
  297. //移除脚本信息
  298. this.crushCell(pos.x,pos.y,false,0);
  299. //下落
  300. this.down();
  301. // let [result, newCellStatus, newCellType, crushPoint] = this.checkPoint(pos.x,pos.y,true);
  302. // console.log("oneResult:",result)
  303. // this.processCrush(result)
  304. // this.processCrush(this.checkPoint(pos.x,pos.y,true))
  305. let onceArray = [];
  306. for (let i = 1;i <= this.gridView.grid_width; i++){
  307. // console.log(i)
  308. for (let j = 1;j <= this.gridView.grid_height; j++){
  309. var [result, newCellStatus, newCellType, crushPoint] = this.checkPoint(i,j,true);
  310. // console.log("oneResult["+i+"]["+j+"]:",result)
  311. if (result.length > 0){
  312. // console.log("if的result:",result)
  313. // this.processCrush(result)
  314. onceArray = mergePointArray(onceArray,result)
  315. }
  316. }
  317. }
  318. this.processCrush(onceArray)
  319. //渲染
  320. return [this.changeModels,this.effectsQueue];
  321. }
  322. // 道具消除整行
  323. processCrushRow(pos){
  324. // console.log("gridView.width4:",this.gridView.grid_width)
  325. // console.log("pcr:",pos)
  326. // console.log("pcr:",pos.y)
  327. this.changeModels = [];
  328. this.effectsQueue = [];
  329. this.curTime = 0;
  330. this.crushNums = 0;
  331. // this.targetOneTypeNum = 0;
  332. // this.targetTwoTypeNum = 0;
  333. // this.targetThreeTypeNum = 0;
  334. //循环点击的行的每个格子
  335. for (let i = 1; i <= this.gridView.grid_width; i++){
  336. // this.crushCell(i,pos.y,false,0)
  337. this.crushRow(i,pos.y,false,0)
  338. // this.addRowCrush(this.curTime,cc.v2(i,pos.y))
  339. // this.down();
  340. }
  341. //下落
  342. this.down();
  343. //定义空数组,用于记录消除整行后还能继续消除的元素
  344. let onceArray = [];
  345. //新格子下落后,再重新循环查找能消除的元素
  346. for (let i = 1;i <= this.gridView.grid_width; i++){
  347. // console.log(i)
  348. for (let j = 1;j <= this.gridView.grid_height; j++){
  349. var [result, newCellStatus, newCellType, crushPoint] = this.checkPoint(i,j,true);
  350. // console.log("oneResult["+i+"]["+j+"]:",result)
  351. //如果找到能消除的元素,则合并到定义的数组里面
  352. if (result.length > 0){
  353. onceArray = mergePointArray(onceArray,result)
  354. }
  355. }
  356. }
  357. //调用消除事件,执行消除
  358. this.processCrush(onceArray)
  359. //渲染
  360. return [this.changeModels,this.effectsQueue];
  361. }
  362. //道具消除整列
  363. processCrushCol(pos){
  364. // console.log("gridView.width5:",this.gridView.grid_width)
  365. // console.log("消除列的pos:",pos)
  366. this.changeModels = [];
  367. this.effectsQueue = [];
  368. this.curTime = 0;
  369. this.crushNums = 0;
  370. // this.targetOneTypeNum = 0;
  371. // this.targetTwoTypeNum = 0;
  372. // this.targetThreeTypeNum = 0;
  373. //循环点击的列的每个格子
  374. for (let i = 1; i <= this.gridView.grid_width; i++){
  375. this.crushCol(pos.x,i,false,0)
  376. }
  377. //下落
  378. this.down();
  379. //定义空数组,用于记录消除整列后还能继续消除的元素
  380. let onceArray = [];
  381. //新格子下落后,再重新循环查找能消除的元素
  382. for (let i = 1;i <= this.gridView.grid_width; i++){
  383. for (let j = 1;j <= this.gridView.grid_height; j++){
  384. var [result, newCellStatus, newCellType, crushPoint] = this.checkPoint(i,j,true);
  385. // console.log("oneResult["+i+"]["+j+"]:",result)
  386. //如果找到能消除的元素,则合并到定义的数组里面
  387. if (result.length > 0){
  388. onceArray = mergePointArray(onceArray,result)
  389. }
  390. }
  391. }
  392. //调用消除事件,执行消除
  393. this.processCrush(onceArray)
  394. //渲染
  395. return [this.changeModels,this.effectsQueue];
  396. }
  397. //道具消除一种类型的格子
  398. processCrushOneType(pos){
  399. // console.log("gridView.width6:",this.gridView.grid_width)
  400. let nowAllCells = this.getCells();
  401. this.changeModels = [];
  402. this.effectsQueue = [];
  403. this.curTime = 0;
  404. this.crushNums = 0;
  405. // this.targetOneTypeNum = 0;
  406. // this.targetTwoTypeNum = 0;
  407. // this.targetThreeTypeNum = 0;
  408. let tempModel = [];
  409. let curType = null;
  410. //两层循环,找出当前点击格子的类型
  411. for (let i = 1; i < nowAllCells.length; i++){
  412. if ( i == pos.y){
  413. // console.log("ii:",i)
  414. for (let j = 1; j < nowAllCells[i].length; j++){
  415. // console.log("nowAllCell["+i+"]"+"["+j+"]:",nowAllCells[i][j])
  416. // console.log("jj:",j)
  417. if (j == pos.x){
  418. // console.log("点击的单元格:",nowAllCells[i][j])
  419. curType = nowAllCells[i][j].type
  420. break;
  421. }
  422. }
  423. break;
  424. }
  425. }
  426. //再次两层循环,找出与点击格子类型相同的所有格子
  427. for (let i = 1; i < nowAllCells.length; i++){
  428. for (let j = 1; j < nowAllCells[i].length; j++){
  429. // console.log("nowAllCell["+i+"]"+"["+j+"]:",nowAllCells[i][j])
  430. // console.log("类型:",nowAllCells[i][j].type)
  431. if (nowAllCells[i][j].type == curType){
  432. tempModel.push(nowAllCells[i][j])
  433. // console.log("ok")
  434. this.crushOneType(j,i,false,0)
  435. }
  436. }
  437. }
  438. this.changeModels = tempModel;
  439. // console.log("重新赋值的changeModels:",this.changeModels)
  440. //下落
  441. this.down();
  442. let onceArray = [];
  443. //新格子下落后,再重新循环查找能消除的元素
  444. for (let i = 1;i <= this.gridView.grid_width; i++){
  445. // console.log(i)
  446. for (let j = 1;j <= this.gridView.grid_height; j++){
  447. var [result, newCellStatus, newCellType, crushPoint] = this.checkPoint(i,j,true);
  448. // console.log("oneResult["+i+"]["+j+"]:",result)
  449. //如果找到能消除的元素,则合并到定义的数组里面
  450. if (result.length > 0){
  451. onceArray = mergePointArray(onceArray,result)
  452. }
  453. }
  454. }
  455. //调用消除事件,执行消除
  456. this.processCrush(onceArray)
  457. //渲染
  458. return [this.changeModels,this.effectsQueue];
  459. }
  460. //生成新cell
  461. createNewCell(pos, status, type){
  462. if (status == ""){
  463. return;
  464. }
  465. if (status == CELL_STATUS.BIRD){
  466. type = CELL_TYPE.BIRD;
  467. }
  468. let model = new CellModel();
  469. this.cells[pos.y][pos.x] = model;
  470. model.init(type);
  471. model.setStartXY(pos.x, pos.y);
  472. model.setXY(pos.x, pos.y);
  473. model.setStatus(status);
  474. model.setVisible(0, false);
  475. model.setVisible(this.curTime, true);
  476. this.changeModels.push(model);
  477. }
  478. //下落
  479. down(){
  480. // console.log("gridView.width7:",this.gridView.grid_width)
  481. let newCheckPoint = [];
  482. for (let i = 1; i <= this.gridView.grid_width; i++){
  483. for (let j = 1; j <= this.gridView.grid_height; j++){
  484. //找到空位
  485. if (this.cells[i][j] == null){
  486. let curRow = i;
  487. //往上找方块
  488. for (let k = curRow; k <= this.gridView.grid_height; k++){
  489. //找到可用的方块
  490. if (this.cells[k][j]){
  491. // console.log("下落:",this.cells[k][j])
  492. this.pushToChangeModels(this.cells[k][j]);
  493. newCheckPoint.push(this.cells[k][j]);
  494. this.cells[curRow][j] = this.cells[k][j];
  495. this.cells[k][j] = null;
  496. this.cells[curRow][j].setXY(j, curRow);
  497. this.cells[curRow][j].moveTo(cc.v2(j, curRow), this.curTime);
  498. curRow++;
  499. }
  500. }
  501. let count = 1;
  502. for (let k = curRow; k <= this.gridView.grid_height; k++){
  503. this.cells[k][j] = new CellModel();
  504. this.cells[k][j].init(this.getRandomCellType());
  505. this.cells[k][j].setStartXY(j, count + this.gridView.grid_height);
  506. this.cells[k][j].setXY(j, count + this.gridView.grid_height);
  507. this.cells[k][j].moveTo(cc.v2(j, k), this.curTime);
  508. count++;
  509. this.changeModels.push(this.cells[k][j]);
  510. newCheckPoint.push(this.cells[k][j]);
  511. // console.log("xialuo")
  512. }
  513. // console.log("下落的newCheckPoint:",newCheckPoint)
  514. }
  515. }
  516. }
  517. this.curTime += ANITIME.TOUCH_MOVE + 0.3;
  518. return newCheckPoint;
  519. }
  520. pushToChangeModels(model){
  521. if (this.changeModels.indexOf(model) != -1){
  522. return;
  523. }
  524. this.changeModels.push(model);
  525. }
  526. cleanCmd(){
  527. // console.log("gridView.width8:",this.gridView.grid_width)
  528. for (let i = 1; i <= this.gridView.grid_width; i++){
  529. for (let j = 1; j <= this.gridView.grid_height; j++){
  530. if (this.cells[i][j]){
  531. this.cells[i][j].cmd = [];
  532. }
  533. }
  534. }
  535. }
  536. exchangeCell(pos1, pos2){
  537. let tmpModel = this.cells[pos1.y][pos1.x];
  538. this.cells[pos1.y][pos1.x] = this.cells[pos2.y][pos2.x];
  539. this.cells[pos1.y][pos1.x].x = pos1.x;
  540. this.cells[pos1.y][pos1.x].y = pos1.y;
  541. this.cells[pos2.y][pos2.x] = tmpModel;
  542. this.cells[pos2.y][pos2.x].x = pos2.x;
  543. this.cells[pos2.y][pos2.x].y = pos2.y;
  544. }
  545. //设置种类
  546. //改成乱序算法
  547. setCellTypeNum(num){
  548. // console.log("num = ",num);
  549. this.cellTypeNum = num;
  550. this.cellCreateType = [];
  551. let createTypeList = this.cellCreateType;
  552. for (let i = 1; i <= CELL_BASENUM; i++){
  553. createTypeList.push(i);
  554. }
  555. for (let i = 0; i < createTypeList.length; i++){
  556. let index = Math.floor(Math.random() * (CELL_BASENUM - i)) + i;
  557. createTypeList[i],createTypeList[index] = createTypeList[index],createTypeList[i];
  558. }
  559. }
  560. //随机生成一个类型
  561. getRandomCellType(){
  562. let index = Math.floor(Math.random() * this.cellTypeNum);
  563. // console.log(index)
  564. return this.cellCreateType[index];
  565. }
  566. //bombModels去重
  567. processBomb(bombModels, cycleCount){
  568. // console.log("gridView.width9:",this.gridView.grid_width)
  569. // console.log("去重")
  570. // console.log("bombModels:",bombModels)
  571. while (bombModels.length > 0){
  572. let newBombModel = [];
  573. let bombTime = ANITIME.BOMB_DELAY;
  574. bombModels.forEach(function (model) {
  575. if (model.status == CELL_STATUS.LINE){
  576. for (let i = 1; i <= this.gridView.grid_width; i++){
  577. if (this.cells[model.y][i]){
  578. if (this.cells[model.y][i].status != CELL_STATUS.COMMON){
  579. newBombModel.push(this.cells[model.y][i]);
  580. }
  581. this.crushCell(i, model.y, false, cycleCount);
  582. }
  583. }
  584. this.addRowBomb(this.curTime, cc.v2(model.x, model.y));
  585. }else if (model.status == CELL_STATUS.COLUMN){
  586. for (let i = 1; i <= this.gridView.grid_height; i++){
  587. if (this.cells[i][model.x]){
  588. if (this.cells[i][model.x].status != CELL_STATUS.COMMON){
  589. newBombModel.push(this.cells[i][model.x]);
  590. }
  591. this.crushCell(model.x, i, false, cycleCount);
  592. }
  593. }
  594. this.addColBomb(this.curTime, cc.v2(model.x, model.y));
  595. }else if (model.status == CELL_STATUS.WRAP){
  596. let x = model.x;
  597. let y = model.y;
  598. for (let i = 1; i <= this.gridView.grid_height; i++){
  599. for (let j = 1; j <= this.gridView.grid_width; j++){
  600. let delta = Math.abs(x - j) + Math.abs(y - i);
  601. if (this.cells[i][j] && delta <= 2){
  602. if (this.cells[i][j].status != CELL_STATUS.COMMON){
  603. newBombModel.push(this.cells[i][j]);
  604. }
  605. this.crushCell(j, i, false, cycleCount);
  606. }
  607. }
  608. }
  609. }else if (model.status == CELL_STATUS.BIRD){
  610. let crushType = model.type;
  611. if (bombTime < ANITIME.BOMB_BIRD_DELAY){
  612. bombTime = ANITIME.BOMB_BIRD_DELAY;
  613. }
  614. if (crushType == CELL_STATUS.BIRD){
  615. crushType = this.getRandomCellType();
  616. }
  617. for (let i = 1; i <= this.gridView.grid_height; i++){
  618. for (let j = 1; j <= this.gridView.grid_width; j++){
  619. if (this.cells[i][j] && this.cells[i][j].type == crushType){
  620. if (this.cells[i][j].status != CELL_STATUS.COMMON){
  621. newBombModel.push(this.cells[i][j]);
  622. }
  623. this.crushCell(j, i, true, cycleCount);
  624. }
  625. }
  626. }
  627. }
  628. },this)
  629. if (bombModels.length > 0){
  630. this.curTime += bombTime;
  631. }
  632. bombModels = newBombModel;
  633. }
  634. }
  635. /**
  636. *
  637. * @param {*开始播放的时间} playTime
  638. * @param {*cell位置} pos
  639. * @param {*第几次消除,用于播放音效} step
  640. */
  641. //普通消除
  642. addCrushEffect(playTime, pos, step){
  643. this.effectsQueue.push({
  644. playTime,
  645. pos,
  646. action:"crush",
  647. step
  648. });
  649. }
  650. //正常消除整行
  651. addRowBomb(playTime, pos){
  652. this.effectsQueue.push({
  653. playTime,
  654. pos,
  655. action:"rowBomb"
  656. });
  657. }
  658. //道具消除整行
  659. addRowCrush(playTime, pos){
  660. this.effectsQueue.push({
  661. playTime,
  662. pos,
  663. action:"crushRow"
  664. });
  665. }
  666. //道具消除整列
  667. addColCrush(playTime, pos){
  668. this.effectsQueue.push({
  669. playTime,
  670. pos,
  671. action:"crushCol"
  672. });
  673. }
  674. //正常消除整列
  675. addColBomb(playTime, pos){
  676. this.effectsQueue.push({
  677. playTime,
  678. pos,
  679. action:"colBomb"
  680. });
  681. }
  682. //道具消除一种类型
  683. addOneTypeCrush(playTime, pos){
  684. this.effectsQueue.push({
  685. playTime,
  686. pos,
  687. action:"typeBomb"
  688. });
  689. }
  690. //分数动画加入队列(按类型消除)
  691. addCrushNums(playTime,pos,nums,oneNums,twoNums,threeNums){
  692. this.effectsQueue.push({
  693. playTime,
  694. pos,
  695. action:"crushNums",
  696. nums, //分数
  697. oneNums, //类型1消除的数量
  698. twoNums, //类型2消除的数量
  699. threeNums, //类型3消除的数量
  700. });
  701. }
  702. //分数动画加入队列(不按类型消除)
  703. addCrushNums(playTime,pos,nums){
  704. this.effectsQueue.push({
  705. playTime,
  706. pos,
  707. action:"crushNums",
  708. nums, //分数
  709. });
  710. }
  711. //cell消除逻辑
  712. crushCell(x, y, needShake, step){
  713. let model = this.cells[y][x];
  714. // console.log("crushCellModel:",model)
  715. this.pushToChangeModels(model);
  716. if (needShake){
  717. model.toShake(this.curTime);
  718. }
  719. let shakeTime = needShake ? ANITIME.DIE_SHAKE : 0;
  720. model.toDie(this.curTime + shakeTime);
  721. this.addCrushEffect(this.curTime + shakeTime, cc.v2(model.x,model.y), step);
  722. this.cells[y][x] = null;
  723. this.crushNums++;
  724. // console.log("消除的类型:",model.type)
  725. // console.log("this.crushNums:",this.crushNums)
  726. //判断消除的类型是否是目标类型
  727. // if (model.type == 1){
  728. // this.targetOneTypeNum++;
  729. // }
  730. // if (model.type == 2){
  731. // this.targetTwoTypeNum++;
  732. // }
  733. // if (model.type == 3){
  734. // this.targetThreeTypeNum++;
  735. // }
  736. }
  737. // 道具消除整行
  738. crushRow(x, y, needShake, step){
  739. let model = this.cells[y][x];
  740. // console.log("crushCellModel:",model)
  741. this.pushToChangeModels(model);
  742. if (needShake){
  743. model.toShake(this.curTime);
  744. }
  745. let shakeTime = needShake ? ANITIME.DIE_SHAKE : 0;
  746. model.toDie(this.curTime + shakeTime);
  747. this.addRowCrush(this.curTime + shakeTime, cc.v2(model.x,model.y), step);
  748. this.cells[y][x] = null;
  749. this.crushNums++;
  750. // console.log("this.crushNums:",this.crushNums)
  751. //判断消除的类型是否是目标类型
  752. // if (model.type == 1){
  753. // this.targetOneTypeNum++;
  754. // }
  755. // if (model.type == 2){
  756. // this.targetTwoTypeNum++;
  757. // }
  758. // if (model.type == 3){
  759. // this.targetThreeTypeNum++;
  760. // }
  761. }
  762. // 道具消除整列
  763. crushCol(x, y, needShake, step){
  764. let model = this.cells[y][x];
  765. // console.log("crushCellModel:",model)
  766. this.pushToChangeModels(model);
  767. if (needShake){
  768. model.toShake(this.curTime);
  769. }
  770. let shakeTime = needShake ? ANITIME.DIE_SHAKE : 0;
  771. model.toDie(this.curTime + shakeTime);
  772. this.addColCrush(this.curTime + shakeTime, cc.v2(model.x,model.y), step);
  773. this.cells[y][x] = null;
  774. this.crushNums++;
  775. // console.log("this.crushNums:",this.crushNums)
  776. //判断消除的类型是否是目标类型
  777. // if (model.type == 1){
  778. // this.targetOneTypeNum++;
  779. // }
  780. // if (model.type == 2){
  781. // this.targetTwoTypeNum++;
  782. // }
  783. // if (model.type == 3){
  784. // this.targetThreeTypeNum++;
  785. // }
  786. }
  787. // 道具消除一种类型
  788. crushOneType(x, y, needShake, step){
  789. let model = this.cells[y][x];
  790. // console.log("crushOneType:",model)
  791. this.pushToChangeModels(model);
  792. if (needShake){
  793. model.toShake(this.curTime);
  794. }
  795. let shakeTime = needShake ? ANITIME.DIE_SHAKE : 0;
  796. model.toDie(this.curTime + shakeTime);
  797. this.addOneTypeCrush(this.curTime + shakeTime, cc.v2(model.x,model.y), step);
  798. this.cells[y][x] = null;
  799. this.crushNums++;
  800. // console.log("this.crushNums:",this.crushNums)
  801. //判断消除的类型是否是目标类型
  802. // if (model.type == 1){
  803. // this.targetOneTypeNum++;
  804. // }
  805. // if (model.type == 2){
  806. // this.targetTwoTypeNum++;
  807. // }
  808. // if (model.type == 3){
  809. // this.targetThreeTypeNum++;
  810. // }
  811. }
  812. }