cocos2d-x3.6 連連看自動消除,cocos2d-x3.6連連看

來源:互聯網
上載者:User

cocos2d-x3.6 連連看自動消除,cocos2d-x3.6連連看

我的部落格:http://blog.csdn.net/dawn_moon

前面已經寫完了連連看的主要邏輯,這一節來講如何自動消除,並且,如果棋盤成了死局以後怎麼辦。

前面章節講解連連看消除演算法的時候講過,後續自動消除演算法也是基於串連演算法的。

原理很簡單,兩層for迴圈,掃描棋盤,判斷是否有串連,如果有,添加串連路徑,如果整個棋盤都沒有可以相連的兩個點,那麼就是死局。

死局如何來解,我這裡的做法是,再隨機打亂現有棋盤,重新布局。

先看死局演算法:

bool GameScene::die(){    for (int y = 1; y < yCount; y++) {        for (int x = 1; x < xCount; x++) {            if (mMap[x][y] != 0) {                for (int j = y; j < yCount - 1; j++) {                    if (j == y) {                        for (int i = x + 1; i < xCount - 1; i++) {                            if (mMap[i][j] == mMap[x][y] && link(Vec2(x, y), Vec2(i, j))) {                                return false;                            }                        }                    }else{                        for (int i = 1; i < xCount - 1; i++) {                            if (mMap[i][j] == mMap[x][y] && link(Vec2(x, y), Vec2(i, j))) {                                return false;                            }                        }                    }                }            }        }    }    return true;}

其實就是幾個遍曆,棋盤上每一個點,和其餘的做連通判斷,漸進式掃描。
因為link函數會將連通的點加入到路徑容器,所以一旦die函數返回false,那麼在路徑容器裡面就已經存了連通路徑的點了。

如果die,那麼就要隨機變化棋盤

    if (die()) {        changeMap();    }

來看changeMap():

void GameScene::changeMap(){    // 隨機種子    srand((unsigned int)time(NULL));    // 臨時變數,用來交換兩個位置的資料    int tempX, tempY, tempM;    // 遍曆地圖數組,隨機交換位置    for (int x = 1; x < xCount - 1 ; x++)        for (int y = 1; y < yCount - 1; y++) {            tempX = 1 + (int)(CCRANDOM_0_1() * (xCount - 2));            tempY = 1 + (int)(CCRANDOM_0_1() * (yCount - 2));            tempM = mMap[x][y];            mMap[x][y] = mMap[tempX][tempY];            mMap[tempX][tempY] = tempM;            // 交換精靈位置,交換tag值            int tag1 = (yCount - 2) * ( x - 1 ) + y;            int tag2 = (yCount - 2) * ( tempX - 1 ) + tempY;            auto pos1 = indextoScreen(x, y);            auto pos2 = indextoScreen(tempX, tempY);            auto pic1 = getChildByTag(tag1);            auto pic2 = getChildByTag(tag2);            if (pic1) {                pic1->setPosition(pos2);                pic1->setTag(tag2);            }else{                // 如果為空白,地圖數組對應值要置0                mMap[tempX][tempY] = 0;            }            if (pic2) {                pic2->setPosition(pos1);                pic2->setTag(tag1);            }else{                mMap[x][y] = 0;            }        }}

我在UI上放一個按鈕,點擊按鈕,就會調用autoClear()函數,就是自動清除機制.

    auto tip = Sprite::createWithTexture(textureCache->getTextureForKey(s_game_leisure));    auto menuItemSprite = MenuItemSprite::create(tip, tip, CC_CALLBACK_1(GameScene::autoClear, this));    auto menu = Menu::create(menuItemSprite, nullptr);    menu->setAnchorPoint(Vec2(1, 1));    menu->setPosition(wSize.width - 100, wSize.height - 100);    addChild(menu);

這裡很簡單,沒有什麼好說的,來看autoClear函數:

void GameScene::autoClear(Ref *spender){    // 左右抖動的動畫    auto rote = RotateBy::create(0.05, 20);    auto seq = Sequence::create(rote, rote->reverse(), rote->reverse(), rote->clone(), nullptr);    ((Sprite*)spender)->runAction(seq);    if (die()) {        CCLOG("die-----");        changeMap();    }else{            drawLine();    }}

好了,就這麼簡單,如果die,那麼變換棋盤,如果沒有die,那麼畫線。
再說一下這個die(),if(die())執行的時候,如果die是true,沒什麼說的,changeMap,如果die返回false,那麼這時候其實已經遍曆了棋盤,講能連通的路徑放到了成員變數mPath裡面,所以就可以直接drawLine()了。

好了,到這裡,連連看基本完成。

著作權聲明:本文為博主原創文章,未經博主允許不得轉載。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.