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