cocos2d 簡單消除遊戲演算法 (一),cocos2d演算法

來源:互聯網
上載者:User

cocos2d 簡單消除遊戲演算法 (一),cocos2d演算法
1. 遊戲視頻示範


2.三消遊戲我的理解
上面視頻中的遊戲,我做了2個星期時間,只能算個簡單Demo,還有bug,特效也幾乎沒有。感覺三消遊戲主要靠磨,越磨越精品。市場上三消遊戲已經超級多了。主流的是地圖型的,幾乎是無盡模式,各種消除特效,各種各樣的過關方式,玩起來還是不錯的,就是遇到比較難的關卡,要多試幾次,運氣非常好的時候就過了,不然卡死。這個遊戲真正擴充的地方就是過關模式,還需要整個特殊的地圖編輯器,配合策劃,不斷升級遊戲。
3.消除涉及到的簡單演算法
3.1 產生隨機地圖演算法



有各種各樣的地圖,這裡拿最簡單的矩形來說。需求:1.這個演算法要產生一個隨機的地圖,不能有3個橫著相同或者3個豎著相同。2.這個地圖使用者移動一步能進行消除(不能是個死地圖)
初看到這個需求感覺還是蠻難的,後來想了下第2個需求應該先別管,如果是死地圖,再重建一張地圖就可以了。測試了下,產生死地圖的機率非常低。
演算法實現的描述:假設地圖的(0,0)在左上方。非常簡單x從上面的最左邊開始往右產生,y從最上面直到底部。每次先判斷下它的左邊兩個是否已經同色,還有上面兩個是否已經同色,如果同色了,要去掉這個顏色。假設已經產生的地圖是:2, 3, 3, 4, 1, 3, 21, 2, 3, 4, 4, 3, 31, 2, 4, 2, 2, X因為X的左邊兩個都是2,所以X不能再是2了,它的上面兩個都是3,所以X不能再是3了。所以X的結果只能是0,1,4中隨機取一個了。
下面是虛擬碼(是不能啟動並執行真代碼):
enum MatchItemType{   kRedItem = 0,         //0   kGreenItem,           //1   kBlueItem,            //2   kWhiteItem,           //3   kOrangeItem           //4};MatchItemType getOneRandomTypeExceptParameter(const MatchItemType& type){    MatchItemType allType[5] = {kRedItem, kGreenItem, kBlueItem, kWhiteItem, kOrangeItem};    std::vector restType;    for(int i = 0; i < 5; ++i){        if(allType[i] != type){            restType.push_back(allType[i]);        }    }    int restSize = restType.size();    int randomIndex = rand() % restSize;        return restType[randomIndex];}Array2D<MatchItemType> getOneRandomMapArray(){    Array2D<MatchItemType> map = Array2D<MatchItemType>(7, 7);    bool findThreeSameInX = false;    bool findThreeSameInY = false;        for(int y = 0; y < 7; ++y){        for(int x = 0; x < 7; ++x){             MatchItemType randomType = (MatchItemType)(rand() % 5);                        if(x >= 2){                //左邊兩個是同色        if( map.Get(x - 1, y) == map.Get(x - 2, y)){                    //need find a new type                    findThreeSameInX = true;                }else{                    findThreeSameInX = false;                }            }else{                findThreeSameInX = false;            }            if(y >= 2){                //上面兩個是同色                if(map.Get(x, y - 1) == map.Get(x, y -2)){                    //need find a new type;                    findThreeSameInY = true;                }else{                    findThreeSameInY = false;                }            }else{                findThreeSameInY = false;            }            if(findThreeSameInX == false && findThreeSameInY == false){               //do nothing            }else if(findThreeSameInX == true && findThreeSameInY == false){                randomType = getOneRandomTypeExceptParameter(map.Get(x - 1, y));            }else if(findThreeSameInX == false && findThreeSameInY == true){                randomType = getOneRandomTypeExceptParameter(map.Get(x, y - 1));            }else{                randomType = getOneRandomTypeExceptParameter(map.Get(x - 1, y),                                                             map.Get(x, y - 1));            }                        map.Set(x, y, randomType);        }    }    return map;}



3.2 判斷地圖是否是死地圖
如果整個地圖,使用者移動任何一步也不能有消除,就是死地圖了,要重建地圖了。

//case 1/////[x]//////[x]//////////[x][o][x][x][o][x]//////////[x]//////[x]///////////////////////////////////case 2////////[x]///////////////////[x][o][x]///////////////////[x]//////////////////////[x]///////////////////[x][o][x]///////////////////[x]//////////////

這裡用注釋畫了簡單的兩種情況,注意x的位置。case1 是橫著有兩個同色的情況,移動一步能消除只有6種可能,左邊3種,右邊3種。下面是豎著有兩個同色的情況,移動一步能消除也是6種情況。上面3種,下面3種。知道了這個,代碼就容易了。記得找到一個就直接return。

vector<MatchItem*> getThreeMatchItemCanRemoveByOneStep(const Array2D<MatchItem*> & map){    vector<MatchItem*> result;        int maxX = 7;    int maxY = 7;            for(int y = 0; y < maxY; ++y){        for(int x = 0; x < maxX; ++x){            if(x + 1 < maxX){                //case 1                if(map.Get(x, y)->getType() == map.Get(x + 1, y)->getType()){                    MatchItemType currentType = map.Get(x, y)->getType();                    //check 6 item, one move one step can combine three same item                    if(x - 2 >= 0){                        if(map.Get(x - 2, y)->getType() == currentType){                            //find one                            result.push_back(map.Get(x, y));                            result.push_back(map.Get(x + 1, y));                            result.push_back(map.Get(x - 2, y));                            return result;                        }                    }                    if(x - 1 >= 0 && y - 1 >= 0){                        if(map.Get(x - 1, y - 1)->getType() == currentType){                            //find one                            result.push_back(map.Get(x, y));                            result.push_back(map.Get(x + 1, y));                            result.push_back(map.Get(x - 1, y - 1));                            return result;                        }                    }                    if(x + 2 < maxX && y - 1 >= 0){                        if(map.Get(x + 2, y - 1)->getType() == currentType){                            //find one                            result.push_back(map.Get(x, y));                            result.push_back(map.Get(x + 1, y));                            result.push_back(map.Get(x + 2, y - 1));                            return result;                        }                    }                    if(x + 3 < maxX){                        if(map.Get(x + 3, y)->getType() == currentType){                            //find one                            result.push_back(map.Get(x, y));                            result.push_back(map.Get(x + 1, y));                            result.push_back(map.Get(x + 3, y));                            return result;                        }                    }                    if(x + 2 < maxX && y + 1 < maxY){                        if(map.Get(x + 2, y + 1)->getType() == currentType){                            //find one                            result.push_back(map.Get(x, y));                            result.push_back(map.Get(x + 1, y));                            result.push_back(map.Get(x + 2, y + 1));                            return result;                        }                    }                    if(x - 1 >= 0 && y + 1 < maxY){                        if(map.Get(x - 1, y + 1)->getType() == currentType){                            //find one                            result.push_back(map.Get(x, y));                            result.push_back(map.Get(x + 1, y));                            result.push_back(map.Get(x - 1, y + 1));                            return result;                        }                    }                }            }            if(y + 1 < maxY){                MatchItemType currentType = map.Get(x, y)->getType();                //case 2                if(map.Get(x, y)->getType() == map.Get(x, y + 1)->getType()){                    if(y - 2 >= 0){                        if(map.Get(x, y - 2)->getType() == currentType){                            //find one                            result.push_back(map.Get(x, y));                            result.push_back(map.Get(x, y + 1));                            result.push_back(map.Get(x, y - 2));                            return result;                        }                    }                    if(x + 1 < maxX && y - 1 >= 0){                        if(map.Get(x + 1, y - 1)->getType() == currentType){                            //find one                            result.push_back(map.Get(x, y));                            result.push_back(map.Get(x, y + 1));                            result.push_back(map.Get(x + 1, y - 1));                            return result;                        }                    }                    if(x + 1 < maxX && y + 2 < maxY){                        if(map.Get(x + 1, y + 2)->getType() == currentType){                            //find one                            result.push_back(map.Get(x, y));                            result.push_back(map.Get(x, y + 1));                            result.push_back(map.Get(x + 1, y + 2));                            return result;                        }                    }                    if(y + 3 < GameGlobal::xMapCount){                        if(map.Get(x, y + 3)->getType() == currentType){                            //find one                            result.push_back(map.Get(x, y));                            result.push_back(map.Get(x, y + 1));                            result.push_back(map.Get(x, y + 3));                            return result;                        }                    }                    if(x - 1 >= 0 && y + 2 < maxY){                        if(map.Get(x - 1, y + 2)->getType() == currentType){                            //find one                            result.push_back(map.Get(x, y));                            result.push_back(map.Get(x, y + 1));                            result.push_back(map.Get(x - 1, y + 2));                            return result;                        }                    }                    if(x - 1 >= 0 && y - 1 >= 0){                        if(map.Get(x - 1, y + 1)->getType() == currentType){                            //find one                            result.push_back(map.Get(x, y));                            result.push_back(map.Get(x, y + 1));                            result.push_back(map.Get(x - 1, y - 1));                            return result;                        }                    }                                    }                        }                    }    }        return result;}

看起來是有點複雜,窮舉了12種情況,這個演算法應該速度很快的。還有個地方要用到這個演算法,就是在消除遊戲中,使用者很久時間沒有進行消除了,要給提示。就用這個演算法找到哪3個可以移動一步進行消除。


演算法先到這裡... 後續有時間再更新...

http://www.waitingfy.com/archives/1335



一個簡單的演算法問題,解答

由內向外層層剝離
for i←1 to n
@x←x+1
end
1+1+1+...+1=n次
for j←1 to n
for i←1 to j
@x←x+1
end
end
A(n)=n
SA(n)=n*(n+1)/2
for i←1 to n
for j←1 to i
for k←1 to j
@x←x+1
end
end
end
B(n)=SA(n)
SB(n)=B(1)+B(2)+...+B(n)
......
方法就是這樣
===================================
1)n*n*(n+1)/2
2)請變成求解
3)請變成求解
===================================
2),3)的結果我不能給出,因為,很顯然,我不是電腦
 
想用cocos2d-x寫一個帶關卡的遊戲,助思路

一個關卡就是一個情境,可以寫成不同的類,也可以寫同樣的類,看個人編程習慣和關卡的具體差異,暫停按鈕每個情境都是要重新addchild的,可以把這些語句自己寫成一個函數,調用就方便了。
 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.