1 /* 2 * 本层拥有处理星星的实例化以及对星星的操作 3 * 1/排列星星 4 * 2/移动和删除星星 5 */ 6 var GAMESTARLAYOUT; 7 var GameStarLayout = ccui.Layout.extend( 8 { 9 size:null, 10 starArr:[],//存放点击与被点击状态的星星资源 11 starObjArr:[],//存放游戏中星星的二位数组 12 firstTouchStar:null,//第一次选择的星星,用于判断两次选择的星星颜色是否一致 13 isSelected:false,//是否选择星星,如果已选择则再次点击将星星消灭 14 starList:[],//相连同色星星列表 15 starNum:0,//当前关卡星星个数 16 ctor:function() 17 { 18 this._super(); 19 this.zinit(); 20 this.layoutStar(); 21 }, 22 //将星星按10*10的矩阵排列出来 23 layoutStar:function() 24 { 25 for(var i = 0; i < 10; i++) 26 { 27 for(var j = 0; j < 10; j++) 28 { 29 //随机从5种不同颜色的星星中选择一个 30 var randomNumber = Math.floor(Math.random()*this.starNum); 31 var starResource = this.starArr[randomNumber]; 32 var star = new GameCreateStar(starResource.normal, starResource.id,starResource.selected, i, j); 33 this.addChild(star, 0); 34 //星星出现的动画 35 var moveTo = cc.moveTo(i/10, cc.p(star.width*i, star.height*j)); 36 star.runAction(moveTo); 37 //将星星装到数组中 38 this.starObjArr[i][j] = star; 39 //给每一个星星注册侦听器 40 star.addTouchEventListener(this.onTouchStarFunc, this); 41 } 42 } 43 }, 44 //星星触摸侦听函数 45 onTouchStarFunc:function(target, state) 46 { 47 if(state == ccui.Widget.TOUCH_ENDED) //松开 48 { 49 if(!this.firstTouchStar) //如果第一次选择的星星为空,则将当前星星赋给它 50 { 51 this.firstTouchStar = target; 52 this.findSameColorStar(target); 53 //如果计分动作未完成则结束动作,取消定时器 54 GAMETOP.cancelSchedule(); 55 } 56 else 57 { 58 if(this.starList.length <1){return;} //确保相连同色星星列表不为空,代码才会向下执行 59 if(this.starList[0].count != target.count) //第二次点击的不是上一次选择的星星 60 { 61 //将列表中的星星type还原 62 this.setStarListItemToNomal(this.starList); 63 this.findSameColorStar(target); 64 } 65 else //第二次点击相连同色星星列表中的星星 66 { 67 if(this.starList.length >1) 68 { 69 this.firstTouchStar = null; 70 this.getScore(); 71 this.resetStarRow(); 72 } 73 } 74 } 75 } 76 }, 77 //消灭信息获得积分 78 getScore:function() 79 { 80 //GAMETOP对象为GameTopInformation的实例; 81 GAMETOP.updateGameScore(this.starList); 82 }, 83 //当消灭星星后,如果上方还有星星存在,则要重新设置他们的row值,用于向下移动星星 84 resetStarRow:function() 85 { 86 for(var i = 0; i < this.starList.length; i++) 87 { 88 this.starList[i].type = -1; 89 this.starList[i].removeFromParent(); 90 for(var j = this.starList[i].row+1; j< 10; j++) 91 { 92 if(!this.starObjArr[this.starList[i].col][j]){continue;} 93 this.starObjArr[this.starList[i].col][j].row--; 94 this.starObjArr[this.starList[i].col][j-1] = this.starObjArr[this.starList[i].col][j]; 95 this.starObjArr[this.starList[i].col][j] = null; 96 } 97 } 98 }, 99 //消灭相连在一起的同色星星 100 removeSameColorStar:function() 101 { 102 for(var i = 0; i < this.starList.length; i++) 103 { 104 //this.starObjArr是二维数组 105 for(var j = 0; j < this.starObjArr.length; j++) 106 { 107 for(var k = 0; k < this.starObjArr.length; k++) 108 { 109 if(!this.starObjArr[j][k]){continue;} 110 if(this.starObjArr[j][k].col == this.starList[i].col && this.starObjArr[j][k].row == this.starList[i].row) 111 { 112 this.starObjArr[j][k].removeFromParent(); 113 } 114 } 115 } 116 } 117 this.starList.splice(0); 118 }, 119 //逐帧监听器,在游戏过程中一直执行 120 update:function() 121 { 122 //检测是否有需要移动的星星(上边的向下移动,右边的向左边移动 123 this.checkMove(); 124 }, 125 //检测是否有需要移动的星星,如果被消除的星星上方还有星星,则上方的需要掉下来,如果这一列为空了且右边还有星星,则右边的需要往做移动 126 checkMove:function() 127 { 128 //检测上方 129 this.checkTop(); 130 }, 131 //检测被移除星星上方是否还有星星,如果有则下移 132 checkTop:function() 133 { 134 var needMove = false; 135 for(var i = 0; i < 10; i++) 136 { 137 for(var j = 0; j < 10; j++) 138 { 139 if(this.starObjArr[i][j] !=null && this.starObjArr[i][j].type != -1) 140 { 141 //向下移动 142 if(this.starObjArr[i][j].y > this.starObjArr[i][j].row*48) 143 { 144 this.starObjArr[i][j].y -= 8; 145 needMove = true; 146 } 147 //向左移动 148 if(this.starObjArr[i][j].x > this.starObjArr[i][j].col*48) 149 { 150 this.starObjArr[i][j].x -= 8; 151 needMove = true; 152 } 153 } 154 } 155 } 156 //当有星星向下移动时,不能移动列 157 if(!needMove) 158 { 159 //检测是否有空列,如果有则把其右边的列向左移动 160 this.checkEmptyColums(); 161 } 162 }, 163 //检测空列 164 checkEmptyColums:function() 165 { 166 var existEmptyCol = false; 167 for(var i = 0; i < 10; i++) 168 { 169 if(!existEmptyCol) 170 { 171 //只有在消灭星星后才能检测空列 172 if(this.firstTouchStar == null) 173 { 174 //当列的最下面元素为空时,说明该列为空 175 if(this.starObjArr[i][0] == null || this.starObjArr[i][0].type == -1) 176 { 177 existEmptyCol = true; 178 } 179 } 180 } 181 //当有空列时,处理列的移动和col属性的设置 182 else if(existEmptyCol) 183 { 184 for(var j = 0; j < 10; j++) 185 { 186 if(this.starObjArr[i][j] != null ) 187 { 188 this.starObjArr[i][j].col--; 189 this.starObjArr[i-1][j] = this.starObjArr[i][j]; 190 this.starObjArr[i][j] = null; 191 } 192 } 193 } 194 } 195 }, 196 //寻找相连在一起同色的星星 197 findSameColorStar:function(target) 198 { 199 //相连同色星星列表 200 this.starList.splice(0); //将列表清空 201 this.starList = this.getSameColorStar(target.col, target.row, target.type); 202 //将满足条件的相连同色星星设为选中状态,玩家能对消除星星数量一幕了然 203 this.showCurrentSameStarSelectedState(this.starList); 204 }, 205 //如果两次选择的不是同种颜色的星星,则将之前选择的星星设为初始状态 206 setStarListItemToNomal:function(starList) 207 { 208 for(var i = 0; i < starList.length; i++) 209 { 210 //还原列表中星星的初始type值 211 starList[i].type = starList[i].normalType; 212 starList[i].isSelected = false; 213 starList[i].updateTexture(); 214 starList[i].count = 0; 215 } 216 }, 217 //将满足条件的相连同色星星设为选中状态 218 showCurrentSameStarSelectedState:function(starList) 219 { 220 for(var i = 0; i < starList.length; i++) 221 { 222 starList[i].isSelected = true; 223 starList[i].updateTexture(); 224 starList[i].count++; 225 } 226 }, 227 //获得相连同色星星列表 228 getSameColorStar:function(col, row, type) 229 { 230 var starList = []; 231 //星星必须在矩阵范围内(9X9) 232 if(this.jugementStarPostion(col, row) == -1) 233 { 234 return starList; 235 } 236 if(this.starObjArr[col][row].type == type) 237 { 238 starList.push(this.starObjArr[col][row]); 239 this.starObjArr[col][row].type = -1; 240 //递归调用,寻找当前星星四周的同色星星 241 starList = starList.concat(this.getSameColorStar(col+1, row, type));//右边 242 starList = starList.concat(this.getSameColorStar(col - 1, row, type));//左边 243 starList = starList.concat(this.getSameColorStar(col, row + 1, type));//上方 244 starList = starList.concat(this.getSameColorStar(col, row - 1, type));//下方 245 } 246 return starList; 247 }, 248 //判断col,row值是否在矩阵范围内, 249 jugementStarPostion:function(col, row) 250 { 251 if(col < 0 ||col >9) //超出水平范围 252 { 253 return -1; 254 } 255 if(row < 0 || row > 9) //超出垂直范围 256 { 257 return -1; 258 } 259 if(this.starObjArr[col][row] == null || this.starObjArr[col][row] == undefined) //该对象不存在 260 { 261 return -1; 262 } 263 return this.starObjArr[col][row].type; 264 }, 265 //检测游戏结束当没有可以消除的星星时游戏宣布结束 266 checkGameOver:function() 267 { 268 //遍历所有的星星 269 for(var i = 0; i < 10; i++) 270 { 271 for(var j = 0; j < 10; j++) 272 { 273 var starType = this.jugementStarPostion(i, j); 274 if(starType == -1){continue;}//不存在星星,则继续下一次循环(当starType =-1时表示该位置没有星星) 275 if(starType == this.jugementStarPostion(i, j+1)){return;}//同理 276 if(starType == this.jugementStarPostion(i+1, j)){return;}//当相邻有相同颜色星星时还回(因为是遍历每一个星星,所以水平方向只需要检测星星相邻右侧是否有相同颜色的就可以了) 277 } 278 } 279 //当没有相同颜色的星星时,宣布游戏结束 280 this.endGame(); 281 }, 282 //游戏结束 283 endGame:function() 284 { 285 //未通关,还回游戏初始界面 286 if(GAMETOP.intermediaryScore < GAMETOP.standardScore) 287 { 288 GAMETOP.passedLevelEffect(res.fail); 289 var delayTime = cc.DelayTime.create(2.2); 290 var callFunc = cc.CallFunc.create(function() 291 { 292 PlayerLocalData.deleteItem();//删除游戏纪录 293 var newGameScene = GameInitializeScene.createScene(); 294 cc.director.runScene(cc.TransitionFade.create(1, newGameScene)); 295 }, this); 296 this.runAction(cc.Sequence.create(delayTime, callFunc)); 297 } 298 else//通过,弹出继续游戏和保存退出按钮 299 { 300 var endX = 240; 301 var endY = 850; 302 var b = 400; 303 var c = 330; 304 //继续游戏 305 var continueGameBtn = new myButton(res.resume); 306 continueGameBtn.setAnchorPoint(0.5, 0.5); 307 continueGameBtn.name = "continueGame"; 308 continueGameBtn.x = endX; 309 continueGameBtn.y = endY 310 this.addChild(continueGameBtn, 1); 311 //action2 312 var moveTo2 = cc.MoveTo.create(4, cc.p(endX, b)); 313 var easeOut2 = moveTo2.clone().easing(cc.easeElasticOut()); 314 continueGameBtn.runAction(easeOut2); 315 //保存退出 316 var saveAndOut = new myButton("img/saveexit.png"); 317 saveAndOut.setAnchorPoint(0.5, 0.5); 318 saveAndOut.name = "save"; 319 saveAndOut.x = endX; 320 saveAndOut.y = endY; 321 this.addChild(saveAndOut, 1); 322 //action3 323 var moveTo3 = cc.MoveTo.create(3, cc.p(endX, c)); 324 var easeOut3 = moveTo3.clone().easing(cc.easeElasticOut()); 325 saveAndOut.runAction(easeOut3); 326 327 continueGameBtn.addTouchEventListener(this.btnControlGameFunc, this); 328 saveAndOut.addTouchEventListener(this.btnControlGameFunc, this); 329 } 330 cc.log("endGame "+" **********************************************************") 331 }, 332 //按钮侦听函数 333 btnControlGameFunc:function(target, state) 334 { 335 if(state == ccui.Widget.TOUCH_ENDED)//松开 336 { 337 switch (target.name) 338 { 339 case "continueGame"://继续游戏 340 var newGameScene = TransitionScene.createScene(false); 341 cc.director.runScene(cc.TransitionFade.create(1, newGameScene)); 342 cc.log("newGame"); 343 break; 344 345 case "save"://保存退出 346 var newGameScene = GameInitializeScene.createScene(); 347 cc.director.runScene(cc.TransitionFade.create(1, newGameScene)); 348 break; 349 350 default: 351 break; 352 } 353 } 354 }, 355 //初始化 356 zinit:function() 357 { 358 this.size = cc.size(480, 500); 359 GAMESTARLAYOUT = this;//对本类的引用对象 360 //设置层的大小 361 this.setSize(this.size); 362 //将星星资源存放到数字中 363 this.starArr = [ 364 {id:1, normal:res.star1, selected:res.star1s}, 365 {id:2, normal:res.star2, selected:res.star2s}, 366 {id:3, normal:res.star3, selected:res.star3s}, 367 {id:4, normal:res.star4, selected:res.star4s}, 368 {id:5, normal:res.star5, selected:res.star5s}, 369 {id:5, normal:res.star5, selected:res.star5s}, 370 {id:5, normal:res.star5, selected:res.star5s}, 371 {id:5, normal:res.star5, selected:res.star5s}, 372 {id:5, normal:res.star5, selected:res.star5s}, 373 {id:5, normal:res.star5, selected:res.star5s}, 374 {id:5, normal:res.star5, selected:res.star5s}, 375 {id:5, normal:res.star5, selected:res.star5s}, 376 {id:5, normal:res.star5, selected:res.star5s}, 377 {id:5, normal:res.star5, selected:res.star5s} 378 ]; 379 for(var i = 0; i < 10; i++) 380 { 381 this.starObjArr.push([]); 382 } 383 //开启侦听器,逐侦监听 384 this.scheduleUpdate(); 385 this.playerGameData = playerGameData;//给玩家信息定义一个新的实例 386 this.levelNumber = this.playerGameData.currentLevel;//玩家达到的关卡数 387 //获得当前关卡的星星个数 388 for(var i = 0; i < levelData.length; i++) 389 { 390 if(this.levelNumber == levelData[i].level) 391 { 392 this.starNum = levelData[i].starNumber; 393 break; 394 } 395 } 396 } 397 }); 398 //实例化 399 GameStarLayout.createLayout = function() 400 { 401 var starLayout = new GameStarLayout(); 402 return starLayout; 403 };