前面几篇已经建立游戏框架和元素,现在还差游戏的主要逻辑:滑动时对卡片的合并计分以及游戏结算检查。现在就来完成卡片合并的逻辑。卡片的合并需要检查各个卡片的数值,这里使用一个二维数组来存储卡片。
首先在GameLayer.h中声明一个二维数组:
//卡片数组 CardSprite* cardArr[4][4];
卡片数组声明后需要初始化,我们在哪里初始化呢?在上一篇文章中我们创建了一个函数createCardSprite创建卡片精灵,将卡片数组的初始化放在该函数中再合适不过了。修改该函数如下:
void GameLayer::createCardSprite(cocos2d::CCSize size) { //获取卡片高宽 int unitSize = ScreenAdapter::GetCardHeight(size.height); //创建4*4个卡片 for (int i=0;i<4;i++) { for (int j=0;j<4;j++) { CardSprite* card = CardSprite::createCardSprite( 2, unitSize, unitSize, unitSize*i+100, unitSize*j+20); //保存卡片到数组中 cardArr[i][j] = card; addChild(card); } } }
完善滑动逻辑如下:
bool GameLayer::doUp() { CCLog("doUp"); bool isdo = false; for (int x = 0; x < 4; x++) { for (int y = 3; y >= 0; y--) { for (int y1 = y - 1; y1 >= 0; y1--) { if (cardArr[x][y1]->getNumber() > 0) { if (cardArr[x][y]->getNumber() <= 0) { cardArr[x][y]->setNumber(cardArr[x][y1]->getNumber()); cardArr[x][y1]->setNumber(0); y++; isdo = true; }else if(cardArr[x][y]->getNumber() == cardArr[x][y1]->getNumber()){ cardArr[x][y]->setNumber(cardArr[x][y]->getNumber()*2); cardArr[x][y1]->setNumber(0); isdo = true; } break; } } } } return isdo; } bool GameLayer::doDown() { CCLog("doDown"); bool isdo = false; for (int x = 0; x < 4; x++) { for (int y = 0; y < 4; y++) { for (int y1 = y + 1; y1 < 4; y1++) { if (cardArr[x][y1]->getNumber() > 0) { if (cardArr[x][y]->getNumber() <= 0) { cardArr[x][y]->setNumber(cardArr[x][y1]->getNumber()); cardArr[x][y1]->setNumber(0); y--; isdo = true; }else if(cardArr[x][y]->getNumber() == cardArr[x][y1]->getNumber()){ cardArr[x][y]->setNumber(cardArr[x][y]->getNumber()*2); cardArr[x][y1]->setNumber(0); isdo = true; } break; } } } } return isdo; } bool GameLayer::doLeft() { CCLog("doLeft"); bool isdo = false; for (int y = 0; y < 4; y++) { for (int x = 0; x < 4; x++) { for (int x1 = x + 1; x1 < 4; x1++) { if (cardArr[x1][y]->getNumber() > 0) { if (cardArr[x][y]->getNumber() <= 0) { cardArr[x][y]->setNumber(cardArr[x1][y]->getNumber()); cardArr[x1][y]->setNumber(0); x--; isdo = true; }else if(cardArr[x][y]->getNumber() == cardArr[x1][y]->getNumber()){ cardArr[x][y]->setNumber(cardArr[x][y]->getNumber()*2); cardArr[x1][y]->setNumber(0); isdo = true; } break; } } } } return isdo; } bool GameLayer::doRight(){ CCLog("doRight"); bool isdo = false; for (int y = 0; y < 4; y++) { for (int x = 3; x >= 0; x--) { for (int x1 = x - 1; x1 >= 0; x1--) { if (cardArr[x1][y]->getNumber() > 0) { if (cardArr[x][y]->getNumber() <= 0) { cardArr[x][y]->setNumber(cardArr[x1][y]->getNumber()); cardArr[x1][y]->setNumber(0); x++; isdo = true; }else if(cardArr[x][y]->getNumber() == cardArr[x1][y]->getNumber()){ cardArr[x][y]->setNumber(cardArr[x][y]->getNumber()*2); cardArr[x1][y]->setNumber(0); isdo = true; } break; } } } } return isdo; }下面以向右滑动来看看具体实现,其他方向原理相同。首先使用两层循环遍历二维数组的每个元素,内层循环依次(向右滑动式合并卡片是从最右边一个开始向左检查遇到相同的数值就合并,但合并后的卡片不再参与合并)遍历行中的元素。接下来检查当前卡片相邻左边一个卡片是否有数值,如果没有就下一次循环;有的话再检查当前卡片是否有值,如果当前卡片没有数值就把左边一个卡片移动(就是使用交换卡片的数值)过来。如果有值又相等就合并卡片。运行起来看看效果