Cocos2d JS 之消滅星星(九) 處理星星類之——移動和消滅星星

  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 };
相關文章
相關標籤/搜索