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 };