cocos2d-x 3.4 之 三消类游戏——万圣大作战(附加篇)
来源:互联网 发布:c语言课程考核内容 编辑:程序博客网 时间:2024/05/16 14:48
***************************************转载请注明出处:http://blog.csdn.net/lttree********************************************
三消游戏——万圣大作战,应该是我最早的教程的教程之一了(总共也没几个o(╯□╰)o)
之前就简单实现了 消除,四消这些;
发布以来,很多人问我 爆炸 肿么办? 五消 肿么办??特效之间交换肿么办???
正好,这段时间找工作,在家呆着,有些时间,就把这个游戏完善一下啦~
PS: 北京有木有 招cocos2d-x 实习生的= =。
好啦,好啦,说正事。
本文将会讲述的内容:
—— 添加 两种特效的产生(爆炸 and 五消(开心消消乐中的 魔力鸟)
—— 添加 两种特效 消除时候的效果
—— 添加 特效之间交换 也会消除并触发相应效果
—— 小修饰(触摸屏蔽)
1. 添加两种特效的产生
这里,首先要总结一下之前的消除:
每个小方格都代表一个精灵,默认是同一个种类的,
—— 带着小三角形的精灵,代表 交换的精灵
然后,总结下来:
① 普通的三消
② 普通的四消,产生 四消特效精灵
③ 普通的五消,产生 五消特效精灵
④、⑤ 变异的五消,产生 爆炸特效精灵
⑥、⑦ 变异的七消,⑥ 产生 五消精灵,⑦ 产生爆炸精灵
当产生上述形状时,所有的精灵都会被消除~
还有,不全消除的情况吗? of course(捉急的英语= =。)
①、② 这种 应该产生三消的情况下,凸出来的那个精灵,不应该被消除
③、④ 这种 应该产生四消的情况下,凸出来的那个精灵,不应该被消除
⑤、⑥、⑦ 这种 应该产生五消的情况下,凸出来的那个精灵,不应该被消除
总之,上面这些情况,凸出来的部分都不应该被消除。
这两个图,基本上涵盖了所有情况( 把上面各种图形 旋转90°、180°、270° )
看出来规律了吗?
什么时候精灵会全部消除?———— 该行或该列 大于等于3!!
产生特效的顺序呢?
>1 如果某行或某列个数 大于等于5 直接产生 五消特效 精灵
BUT,是否要消除 另外一个方向的所有精灵,就要看个数是否大于等于3了。
>2 如果某行或某列个数 大于等于4
先判断 交换精灵 的另一个方向精灵个数 是否大于等于3,
—— ≥3 则,产生爆炸特效精灵,并且全部消除
—— <3 则,产生四消特效精灵,只消除 ≥4 的那个方向的精灵
>3 如果 某行或某列的个数 大于等于3
判断 交换精灵 另一个方向精灵个数 是否大于等于 3
—— ≥3 则,产生 爆炸特效精灵,并且全部消除
—— <3 则,普通三消,只消除≥3 那个方向的精灵
逻辑已经清楚了,我们就可以直接改代码了。
找到 GameScene.cpp :
checkAndRemove函数: 用来检查并移除相应精灵
void GameScene::checkAndRemoveSprite(){SpriteShape *spr; // 设定寿司的忽视检查for( int r = 0 ; r < ROWS ; ++r ){for( int c = 0 ; c < COLS ; ++c ){spr = map[r][c];if( !spr ){continue;}spr -> setIgnoreCheck(false);}}for( int r = 0 ; r < ROWS ; ++r ){for( int c = 0 ; c < COLS ; ++c ){spr = map[r][c];if( !spr ){continue;}if( spr -> getIsNeedRemove() ){continue;}// 新变化的特殊寿司,不消除if ( spr -> getIgnoreCheck() ) {continue;}removeAndPro(spr);}}// 3.消除标记了的寿司removeSprite();}
removeAndPro函数: 查找某个精灵 横向 纵向个数,并且判断是什么样的消除(其实也是为了避免checkAndRemove函数过长)
void GameScene::removeAndPro(SpriteShape *spr){// 获取 横竖 两方向精灵std::list< SpriteShape *> colChainList;getColChain( spr , colChainList );std::list< SpriteShape *> rowChainList;getRowChain( spr , rowChainList );// 如果任意一方向的精灵都小于3个,直接return,不需要继续往下看了if( rowChainList.size() < 3 && colChainList.size() < 3 ){return;}CCLOG("row:%d,col:%d",rowChainList.size(),colChainList.size());// 判断是交换产生的特效消除 还是 自由掉落 产生的特效消除bool isChangePro = false;if( rowChainList.size() >= 5 ){// 两方向精灵全部消除 并 产生五消除精灵(魔力鸟)if( colChainList.size() >= 3 ){removeListSpr(rowChainList,true,DISPLAY_MODE_ANY,isChangePro);removeListSpr(colChainList,false,DISPLAY_MODE_ANY,isChangePro);// 自由掉落产生if( isChangePro == false ){spr->setIgnoreCheck(true);spr->setIsNeedRemove(false);spr->setDisplayMode(DISPLAY_MODE_ANY);}} // 只消除 横向 精灵 ,产生五消精灵else{removeListSpr(rowChainList,true,DISPLAY_MODE_ANY,isChangePro);// 自由掉落产生if( isChangePro == false ){spr->setIgnoreCheck(true);spr->setIsNeedRemove(false);spr->setDisplayMode(DISPLAY_MODE_ANY);}}return;}if( colChainList.size() >= 5 ){if( rowChainList.size() >= 3 ){// 两方向精灵全部消除 并 产生五消除精灵(魔力鸟)removeListSpr(colChainList,true,DISPLAY_MODE_ANY,isChangePro);removeListSpr(rowChainList,false,DISPLAY_MODE_ANY,isChangePro);// 自由掉落产生if( isChangePro == false ){spr->setIgnoreCheck(true);spr->setIsNeedRemove(false);spr->setDisplayMode(DISPLAY_MODE_ANY);}}else{// 只消除 纵向 精灵 ,产生五消精灵removeListSpr(colChainList,true,DISPLAY_MODE_ANY,isChangePro);// 自由掉落产生if( isChangePro == false ){spr->setIgnoreCheck(true);spr->setIsNeedRemove(false);spr->setDisplayMode(DISPLAY_MODE_ANY);}}return;}if( rowChainList.size() >= 4 ){if( colChainList.size() >= 3 ){// 两方向精灵都消除,产生爆炸精灵removeListSpr(rowChainList,true,DISPLAY_MODE_BOMB,isChangePro);removeListSpr(colChainList,false,DISPLAY_MODE_BOMB,isChangePro);// 自由掉落产生if( isChangePro == false ){spr->setIgnoreCheck(true);spr->setIsNeedRemove(false);spr->setDisplayMode(DISPLAY_MODE_BOMB);}}else{// 消除 横向精灵,产生四消精灵removeListSpr(rowChainList,true,DISPLAY_MODE_VERTICAL,isChangePro);// 自由掉落产生if( isChangePro == false ){spr->setIgnoreCheck(true);spr->setIsNeedRemove(false);spr->setDisplayMode(DISPLAY_MODE_VERTICAL);}}return;}if( colChainList.size() >= 4 ){if( rowChainList.size() >= 3 ){// 两方向精灵都消除,产生爆炸精灵removeListSpr(colChainList,true,DISPLAY_MODE_BOMB,isChangePro);removeListSpr(rowChainList,false,DISPLAY_MODE_BOMB,isChangePro);// 自由掉落产生if( isChangePro == false ){spr->setIgnoreCheck(true);spr->setIsNeedRemove(false);spr->setDisplayMode(DISPLAY_MODE_BOMB);}}else{// 消除 纵向精灵,产生四消精灵removeListSpr(colChainList,true,DISPLAY_MODE_HORIZONTAL,isChangePro);// 自由掉落产生if( isChangePro == false ){spr->setIgnoreCheck(true);spr->setIsNeedRemove(false);spr->setDisplayMode(DISPLAY_MODE_HORIZONTAL);}}return;}if( rowChainList.size() >= 3 ){if( colChainList.size() >= 3 ){// 两方向精灵都消除,产生爆炸精灵removeListSpr(rowChainList,true,DISPLAY_MODE_BOMB,isChangePro);removeListSpr(colChainList,false,DISPLAY_MODE_BOMB,isChangePro);// 自由掉落产生if( isChangePro == false ){spr->setIgnoreCheck(true);spr->setIsNeedRemove(false);spr->setDisplayMode(DISPLAY_MODE_BOMB);}}else{// 消除横向精灵removeListSpr(rowChainList,false,DISPLAY_MODE_BOMB,isChangePro);}return;}if( colChainList.size() >= 3 ){if( rowChainList.size() >= 3 ){removeListSpr(colChainList,true,DISPLAY_MODE_BOMB,isChangePro);removeListSpr(rowChainList,false,DISPLAY_MODE_BOMB,isChangePro);// 自由掉落产生if( isChangePro == false ){spr->setIgnoreCheck(true);spr->setIsNeedRemove(false);spr->setDisplayMode(DISPLAY_MODE_BOMB);}}else{// 消除纵向精灵removeListSpr(colChainList,false,DISPLAY_MODE_BOMB,isChangePro);}return;}}
removeListSpr函数:消除某个容器内所有精灵
// 移除某个容器的所有精灵void GameScene::removeListSpr(std::list<SpriteShape *> &chainList,bool findSpe,DisplayMode dm,bool &isChangePro){// 遍历用的迭代器std::list<SpriteShape *>::iterator itList;SpriteShape *sprite;for( itList = chainList.begin();itList != chainList.end();++itList ) {sprite = ( SpriteShape * )* itList;if( !sprite ){continue;}if( findSpe ){if ( sprite == staSprite || sprite == endSprite ) {isChangePro = true;// 如果交换消除的带特效if( sprite->getDisplayMode() != DISPLAY_MODE_NORMAL ){markRemove(sprite);sprite->setIsNeedRemove(false);sprite->setDisplayMode(dm);}else{sprite->setIgnoreCheck(true);sprite->setIsNeedRemove(false);sprite->setDisplayMode(dm);}}}markRemove( sprite );}}
现在,所有的消除都能产生相应的消除特效了。
2.添加两种特效消除的效果
在改动之前,一定要明确,消除的流程是什么样的:
> 接受触摸,交换精灵,遍历数组看是否有可以消除的精灵 checkAndRemove函数
> 查看 精灵 应该如何消除(是否产生特效精灵),removeAndPro函数
> 标记应该消除的精灵,markRemove函数
> 所有都标记完后,执行消除函数,removeSprite函数
产生两种特效的效果,主要在于 后面两个 函数,
markRemove函数 与 removeSprite函数。
markRemove函数,是将 精灵 的消除属性,置true,便于后面在removeSprite中判断而执行消除。
在removeSprite中,遍历所有的精灵,将消除属性为 true 的,执行explodeSprite函数,播放动画什么的。
而且还要根据 它的类型(横向或者纵向),执行特殊的动画效果。
这次,爆炸和五消特效,我只执行了消除,并没有像 开心消消乐 那种,还有动画。
接下里是,代码部分:
markRemove函数
void GameScene::markRemove( SpriteShape* spr ){ if ( spr -> getIsNeedRemove()) { return; } if ( spr -> getIgnoreCheck() ) { return; } // 自己本身要消除 spr -> setIsNeedRemove(true); // 查看所需要消除的精灵是什么类型的// 如果是 纵向消除 的精灵 if ( spr ->getDisplayMode() == DISPLAY_MODE_VERTICAL) { for ( int r = 0; r < ROWS ; ++r ) {SpriteShape* tmp = map[r][spr->getCol()]; if ( !tmp || tmp == spr ) { continue; } if (tmp->getDisplayMode() == DISPLAY_MODE_NORMAL) { tmp->setIsNeedRemove(true); } else { markRemove(tmp); } } // 如果消除的是 横向消除特效 的精灵 } else if ( spr -> getDisplayMode() == DISPLAY_MODE_HORIZONTAL) { for (int c = 0; c < COLS ; ++c ) { SpriteShape *tmp = map[ spr -> getRow()][c]; if (!tmp || tmp == spr) { continue; } if (tmp->getDisplayMode() == DISPLAY_MODE_NORMAL) { tmp->setIsNeedRemove(true); } else { markRemove(tmp); } } }// 消除的是 炸弹特效 的精灵else if( spr->getDisplayMode() == DISPLAY_MODE_BOMB ){int dir[12][2] = {0,-2,-2,0,0,2,2,0,0,-1,-1,-1,-1,0,-1,1,0,1,1,1,1,0,1,-1};int tempX,tempY;for( int i = 0 ; i < 12 ; i++ ){tempX = spr->getRow()+dir[i][0];tempY = spr->getCol()+dir[i][1];if( tempX >= 0 && tempX < ROWS && tempY >= 0 && tempY < COLS && map[tempX][tempY] ){if (map[tempX][tempY]->getDisplayMode() == DISPLAY_MODE_NORMAL) {map[tempX][tempY]->setIsNeedRemove(true);} else {markRemove(map[tempX][tempY]);}}}}// 消除的是 五消特效 的精灵else if( spr->getDisplayMode() == DISPLAY_MODE_ANY ){// 如果是交换 执行 五消除if( staSprite && (staSprite->getDisplayMode()==DISPLAY_MODE_ANY || endSprite->getDisplayMode()==DISPLAY_MODE_ANY) ){if( staSprite->getDisplayMode() == DISPLAY_MODE_ANY ){for( int r = 0 ; r < ROWS ; r++ ){for( int c = 0 ; c < COLS ; c++ ){SpriteShape *tmp = map[r][c];if (!tmp || tmp == spr) {continue;}if( tmp->getImgIndex() == endSprite->getImgIndex() ){if (tmp->getDisplayMode() == DISPLAY_MODE_NORMAL) {tmp->setIsNeedRemove(true);} else {markRemove(tmp);}}}}}else{for( int r = 0 ; r < ROWS ; r++ ){for( int c = 0 ; c < COLS ; c++ ){SpriteShape *tmp = map[r][c];if (!tmp || tmp == spr) {continue;}if( tmp->getImgIndex() == staSprite->getImgIndex() ){if (tmp->getDisplayMode() == DISPLAY_MODE_NORMAL) {tmp->setIsNeedRemove(true);} else {markRemove(tmp);}}}}}}// 并非交换执行 五消除else{// 随机消除某个int _rand = myRand_0_1()*(TOTAL_SP-1);for( int r = 0 ; r < ROWS ; r++ ){for( int c = 0 ; c < COLS ; c++ ){SpriteShape *tmp = map[r][c];if (!tmp || tmp == spr) {continue;}if( tmp->getImgIndex() == _rand ){if (tmp->getDisplayMode() == DISPLAY_MODE_NORMAL) {tmp->setIsNeedRemove(true);} else {markRemove(tmp);}}}}}}}
注意到,里面可能嵌套markRemove函数,因为,如果你消除一行的时候,那一行中恰好别的特效精灵,就将它扔进markRemove函数里,一个简单的递归。
在 触发爆炸特效的时候,我是类似于以前做算法 搜索时候的习惯,把相对位置构成一个数组,然后直接遍历就可以了。
在 触发 五消特效的时候,我要先找到 哪个是五消类型,哪个是 另一个精灵,再根据另一个精灵的类型 进行mark,
比如 如果是普通的精灵,就直接将所有同类型的mark就行了,
如果是 特效的,就根据开心消消乐的规则 先赋予特效,再mark。
removeSprite函数
// 移除精灵void GameScene::removeSprite(){// 做一套移除的动作 isAction = true; for( int r = 0 ; r < ROWS ; ++r ){for( int c = 0 ; c < COLS ; ++c ){SpriteShape* spr = map[r][c];if( !spr ){continue;}if( spr -> getIsNeedRemove() ){isFillSprite = true;if( spr->getDisplayMode() == DISPLAY_MODE_HORIZONTAL){this->m_time += 3;addTime();explodeSpecialH( spr->getPosition() );}else if (spr->getDisplayMode() == DISPLAY_MODE_VERTICAL){this->m_time += 3;addTime();explodeSpecialV( spr->getPosition() );}else if (spr->getDisplayMode() == DISPLAY_MODE_BOMB ){this->m_time += 3;addTime();}else if( spr->getDisplayMode() == DISPLAY_MODE_ANY ){this->m_time += 3;addTime();}explodeSprite( spr );}}}}
其实,没什么大改变,因为我没有添加额外的动画,所以就是简简单单在触发特效的时候的时间的增加。
恩,现在,两个特效就有了。
3.添加 特效之间交换 也会消除并触发相应效果
这个就是特效之间交换也可以消除,比如 纵向消除 与 横向消除交换,即使它们不是同一种类型,交换后也不会构成消除,也可以触发各自的特效。
规则是这样的:
—— 横向消除 与 横向消除 、纵向消除 与 纵向消除 、爆炸 与 爆炸 、横向消除 与 纵向消除
直接交换,然后触发各自特效就行了
—— 横向消除 与 爆炸,交换后 横向消除那个精灵的 上一行 与 下一行 也同时消除(就是三行的消除)
—— 纵向消除 与 爆炸,交换后 纵向消除的那个精灵 上一列 与 下一列 也同时消除(就是三列的消除)
—— 五消 与 五消, 应该是先触发所有的特效,等下落以后 全爆炸(我图简单,直接就全消除了)
五消 与 横向消除or纵向消除,随机 将所有同类型精灵 变成横消或纵消 再消除掉
五消 与 爆炸,将所有同类型精灵 变成 爆炸特效,再消除掉
然后,这个判断,应该是在交换精灵那里,就是当我们触摸(滑动)后,执行交换,交换后会判断有没有可以消除的精灵,在这里,我们就应该判断 交换的两个精灵是否均不是 特效精灵。
void GameScene::swapSprite(){// 移动中,不允许再次触摸,执行动作设置为true isAction = true; isTouchEna = false;if (!staSprite || !endSprite) { return; } Point posOfSrc = staSprite->getPosition();Point posOfDest = endSprite->getPosition(); float time = 0.1; // 在数组中交换位置map[ staSprite -> getRow() ][staSprite -> getCol() ] = endSprite;map[ endSprite -> getRow() ][endSprite -> getCol() ] = staSprite; int tmpRow = staSprite->getRow(); int tmpCol = staSprite->getCol(); staSprite->setRow(endSprite->getRow()); staSprite->setCol(endSprite->getCol()); endSprite->setRow(tmpRow); endSprite->setCol(tmpCol); // 交换的两个精灵都是特效,或者其中有一个是 五消if( (staSprite->getDisplayMode()!=DISPLAY_MODE_NORMAL && endSprite->getDisplayMode()!=DISPLAY_MODE_NORMAL) || (staSprite->getDisplayMode()==DISPLAY_MODE_ANY || endSprite->getDisplayMode()==DISPLAY_MODE_ANY) ){// 如果能够消除,仅仅进行移动(不会移动回来) staSprite->runAction(MoveTo::create(time, posOfDest)); endSprite->runAction(MoveTo::create(time, posOfSrc));// 判断是哪两个特效交换// 如果两个特效类型相同,并且不是 五消特效if( staSprite->getDisplayMode()==endSprite->getDisplayMode() ){// 如果是两个五消特效交换if( staSprite->getDisplayMode()==DISPLAY_MODE_ANY ){// 全屏消除SpriteShape *spr;for( int r = 0 ; r < ROWS ; r++ ){for( int c = 0 ; c < COLS ; c++ ){spr = map[r][c];markRemove(spr);}}}else{markRemove(staSprite);markRemove(endSprite);}}// 如果 有一个特效是炸弹else if( staSprite->getDisplayMode()==DISPLAY_MODE_BOMB || endSprite->getDisplayMode()==DISPLAY_MODE_BOMB ){// 找到哪个是炸弹if( staSprite->getDisplayMode()==DISPLAY_MODE_BOMB ){// 查看另一个特效// 横向消除特效if( endSprite->getDisplayMode()==DISPLAY_MODE_HORIZONTAL ){int dir[3] = {-1,0,1};SpriteShape *spr;for( int i = 0 ; i < 3 ; i++ ){if( endSprite->getRow()+dir[i] >= 0 && endSprite->getRow()+dir[i] < ROWS ){spr = map[endSprite->getRow()+dir[i]][endSprite->getCol()];spr->setDisplayMode(DISPLAY_MODE_HORIZONTAL);markRemove(spr);}}}// 纵向消除特效else if( endSprite->getDisplayMode()==DISPLAY_MODE_VERTICAL ){int dir[3] = {-1,0,1};SpriteShape *spr;for( int i = 0 ; i < 3 ; i++ ){if( endSprite->getCol()+dir[i] >= 0 && endSprite->getCol()+dir[i] < COLS ){spr = map[endSprite->getRow()][endSprite->getCol()+dir[i]];spr->setDisplayMode(DISPLAY_MODE_VERTICAL);markRemove(spr);}}}// 五消特效else if( endSprite->getDisplayMode()==DISPLAY_MODE_ANY ){SpriteShape *spr;for( int r = 0 ; r < ROWS ; r++ ){for( int c = 0 ; c < COLS ; c++ ){spr = map[r][c];if( spr->getImgIndex() == endSprite->getImgIndex() ){spr->setDisplayMode(DISPLAY_MODE_BOMB);markRemove(spr);}}}}}else{// 查看另一个特效// 横向消除特效if( staSprite->getDisplayMode()==DISPLAY_MODE_HORIZONTAL ){int dir[3] = {-1,0,1};SpriteShape *spr;for( int i = 0 ; i < 3 ; i++ ){if( staSprite->getRow()+dir[i] >= 0 && staSprite->getRow()+dir[i] < ROWS ){spr = map[staSprite->getRow()+dir[i]][staSprite->getCol()];spr->setDisplayMode(DISPLAY_MODE_HORIZONTAL);markRemove(spr);}}}// 纵向消除特效else if( staSprite->getDisplayMode()==DISPLAY_MODE_VERTICAL ){int dir[3] = {-1,0,1};SpriteShape *spr;for( int i = 0 ; i < 3 ; i++ ){if( staSprite->getCol()+dir[i] >= 0 && staSprite->getCol()+dir[i] < COLS ){spr = map[staSprite->getRow()][staSprite->getCol()+dir[i]];spr->setDisplayMode(DISPLAY_MODE_VERTICAL);markRemove(spr);}}}// 五消特效else if( staSprite->getDisplayMode()==DISPLAY_MODE_ANY ){SpriteShape *spr;for( int r = 0 ; r < ROWS ; r++ ){for( int c = 0 ; c < COLS ; c++ ){spr = map[r][c];if( spr->getImgIndex() == staSprite->getImgIndex() ){spr->setDisplayMode(DISPLAY_MODE_BOMB);markRemove(spr);}}}}}}// 如果 有一个特效是 五消else if( staSprite->getDisplayMode()==DISPLAY_MODE_ANY || endSprite->getDisplayMode()==DISPLAY_MODE_ANY ){if( staSprite->getDisplayMode() == DISPLAY_MODE_ANY ){if( endSprite->getDisplayMode() == DISPLAY_MODE_NORMAL ){markRemove(staSprite);markRemove(endSprite);}// 另一个是 竖消 或者 横消else{SpriteShape *spr;for( int r = 0 ; r < ROWS ; r++ ){for( int c = 0 ; c < COLS ; c++ ){spr = map[r][c];if( spr->getImgIndex() == endSprite->getImgIndex() ){// 随机 横消或者竖消float _rand = myRand_0_1();if( _rand < 0.5 ){spr->setDisplayMode(DISPLAY_MODE_HORIZONTAL);}else{spr->setDisplayMode(DISPLAY_MODE_VERTICAL);}markRemove(spr);}}}}}else{if( staSprite->getDisplayMode() == DISPLAY_MODE_NORMAL ){markRemove(staSprite);markRemove(endSprite);}// 另一个是 竖消 或者 横消else {SpriteShape *spr;for( int r = 0 ; r < ROWS ; r++ ){for( int c = 0 ; c < COLS ; c++ ){spr = map[r][c];if( spr->getImgIndex() == staSprite->getImgIndex() ){// 随机 横消或者竖消float _rand = myRand_0_1();if( _rand < 0.5 ){spr->setDisplayMode(DISPLAY_MODE_HORIZONTAL);}else{spr->setDisplayMode(DISPLAY_MODE_VERTICAL);}markRemove(spr);}}}}}}// 剩下的就是 横消+竖消组合else{markRemove(staSprite);markRemove(endSprite);}removeSprite(); return;} // 检查是否能消除std::list<SpriteShape *> colChainListOfFirst; getColChain(staSprite, colChainListOfFirst); std::list<SpriteShape *> rowChainListOfFirst; getRowChain(staSprite, rowChainListOfFirst); std::list<SpriteShape *> colChainListOfSecond; getColChain(endSprite, colChainListOfSecond); std::list<SpriteShape *> rowChainListOfSecond; getRowChain(endSprite, rowChainListOfSecond); if (colChainListOfFirst.size() >= 3 || rowChainListOfFirst.size() >= 3 || colChainListOfSecond.size() >= 3 || rowChainListOfSecond.size() >= 3 || staSprite->getDisplayMode()==DISPLAY_MODE_ANY || endSprite->getDisplayMode()==DISPLAY_MODE_ANY) { // 如果能够消除,仅仅进行移动(不会移动回来) staSprite->runAction(MoveTo::create(time, posOfDest)); endSprite->runAction(MoveTo::create(time, posOfSrc)); return; } // 不能消除,则移动过去还要返回map[ staSprite -> getRow()][staSprite -> getCol() ] = endSprite;map[ endSprite -> getRow()][endSprite -> getCol() ] = staSprite; tmpRow = staSprite->getRow(); tmpCol = staSprite->getCol(); staSprite->setRow(endSprite->getRow()); staSprite->setCol(endSprite->getCol()); endSprite->setRow(tmpRow); endSprite->setCol(tmpCol); staSprite->runAction(Sequence::create( MoveTo::create(time, posOfDest), MoveTo::create(time, posOfSrc), NULL)); endSprite->runAction(Sequence::create( MoveTo::create(time, posOfSrc), MoveTo::create(time, posOfDest), NULL));}
这里的判断顺序是这样的:
——是否同类型
————其中一个为 五消(肯定另一个也是五消了)
——其中一个为 炸弹
————另一个为 横消
————另一个为 纵消
————另一个为 五消
——其中一个为 五消
————另一个为 普通精灵
————另一个为 横消 或 纵消
——剩下 就是 横消+纵消 的组合了
这个 if-else 关系,不知道能不能看懂= =。
4.触摸屏蔽 and 交换处 优先判断
这里有些小问题,我们在判断它有哪些精灵爆炸的时候,有先后顺序。
比如,上面 第一张图 T字形,产生五消的形状。
如果我们,直接两个for循环,从0~ROWS ,0~COLS,来判断形状生成特效的话,的确可以产生五消特效,但是,凸出来的那部分(应该消除的),没有被消除,因为按我们的判断逻辑,是从头开始判断,看下面图:(图好丑啊= =。)
我们从 1号开始判断,横向5个,纵向1个(假设),所以,要产生 五消特效精灵,
staSprite或者endSprite肯定是3号那个,所以,3变成五消特效,1,2,4,5会消除,6,7反而会留下。
但,正确的应该是,3变成五消特效,1,2,4,5,6,7 消除。
所以,应该就先判断交换处的精灵关系,再从头开始遍历。
if( staSprite!=NULL && !staSprite->getIsNeedRemove() && !staSprite->getIgnoreCheck() ){ removeAndPro(staSprite);}if( endSprite!=NULL && !endSprite->getIsNeedRemove() && !endSprite->getIgnoreCheck() ){ removeAndPro(endSprite);}
最后,之前 游戏结束,还可以进行交换,我这里就加上一个触摸屏蔽层把。
非常简单,就是游戏结束的时候,加一个layer,这个layer将 触摸事件吞掉。
//*********SwallowLayer.h#ifndef __SWALLOWLAYER_H__#define __SWALLOWLAYER_H__#include "cocos2d.h"USING_NS_CC;class SwallowLayer : public Layer{public:/***** 初始化函数 *****/virtual bool init(); CREATE_FUNC(SwallowLayer);};#endif//******** SwallowLayer.cpp#include "SwallowLayer.h"bool SwallowLayer::init( ){if( !Layer::init() ){return false;} // 添加监听器auto listener = EventListenerTouchOneByOne::create();listener->onTouchBegan= [this](Touch* t,Event* e){CCLOG("touch swallow layer");return true;};listener->setSwallowTouches(true);Director::getInstance()->getEventDispatcher()->addEventListenerWithSceneGraphPriority(listener, this);return true;}
好了,大体已经完成了。
虽然,还有一些瑕疵,唉。。。
马上就去北京找实习了,祝自己好运吧~= =~
本篇 完整代码+资源:百度云盘
本篇 最终 APK:百度云盘
***************************************转载请注明出处:http://blog.csdn.net/lttree********************************************
- cocos2d-x 3.4 之 三消类游戏——万圣大作战(附加篇)
- cocos2d-x 3.2 之 三消类游戏——万圣大作战
- cocos2d-x 3.2 之 三消类游戏——万圣大作战 (第二篇)
- cocos2d-x 3.2 之 三消类游戏——万圣大作战 (第三篇)
- cocos2d-x 3.2 之 三消类游戏——万圣大作战 (第四篇)
- cocos2d-x 3.2 之 三消类游戏——万圣大作战 (第五篇)
- cocos2d-x 3.2 之 三消类游戏——万圣大作战 (第一篇)
- Cocos2d-x的学习之路——球球大作战手游开发
- 《iOS游戏编程之从零开始—Cocos2d-x与cocos2d引擎游戏开发(配光盘)》
- Cocos2d—X游戏开发之cookie存取(八)
- Cocos2d—X游戏开发之CCEditBox(虚拟键盘高级篇)(十)
- Cocos2d-x 实战之数字三消类游戏
- Cocos2d-X之游戏存储Sqlite基础篇(四)
- Cocos2d-X之游戏存储Sqlite高级篇(四)
- cocos2d-x游戏开发(一)之环境搭建篇
- Cocos2d-X之游戏存储Sqlite基础篇(四)
- Cocos2d—X游戏开发之单例设计模式
- Cocos2d—X游戏开发之LibCurl高级篇(get,post服务器数据)(网络详细参数信息)
- 暗黑战神客户端(IOS和Android)打包教程
- android代码书写规范
- 控制ListView滑动速度
- iOS-UITableviewCell的重用机制
- Android实战简易教程-第六十三枪(动画实现唱片播放界面)
- cocos2d-x 3.4 之 三消类游戏——万圣大作战(附加篇)
- sql ————视图
- 简单快速的word转成pdf转换方法
- 触发器
- 磁盘基础
- MongoDB快速启动方法
- MySQL索引
- Java学习9.29
- linux常用工具系列------git