zoukankan      html  css  js  c++  java
  • 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 };
  • 相关阅读:
    nor flash之4字节地址模式
    DroidVim:在安卓手机上使用vim
    从linux命令行分享文件:bashupload.com和transfer.sh
    记一个实时Linux的中断线程化问题
    nor flash之写保护开销
    第七届开源操作系统会议(OS2ATC 2019)见闻及资料分享
    nor flash之擦除和写入
    PyCharm 远程调试代码
    【图像分析】形态学
    【强化学习】DQN 算法改进
  • 原文地址:https://www.cnblogs.com/zfsSuperDream/p/4080947.html
Copyright © 2011-2022 走看看