學習連連看 連線線之謎+道具的使用

你的財神爺發表於2018-01-16

  下面講解今天的重頭戲,就是如何吧兩個符合規則的圖片連結起來。這個雜眼看起來很簡單,不過BOY 也是費了很大的周折。

       其實我發現連連第二個重要的演算法就是這個了。不過BOY 想到了一個很簡單的解決辦法。

       下面就講解一下。

      

          大家看到這個連線的紅線了,或許剛開始 可能看不出來這有什麼規律,我也是研究和一下,看看希望怎麼把這個演算法告訴大家。
大家看到這個紅線的時候 主要看那兩個拐角的地方。其實在做的時候BOY 發現所有的線都是指向拐角處的。我畫個圖大家就明白了。

通過上一章的演算法講解我們很容易知道 那個拐角處的點是什麼,如果對著一點不明白的先看看上一章連連看的演算法。
這裡有的朋友要問了,那沒有拐角的怎麼辦呢,其實很好辦,我之所以非要知道這個拐角是因為,這個拐角就是這個連結的結束。對已沒有拐角的我就假設一個拐角,讓其中的一條線指向他就可以了。簡答一點說就是連連看中所有的連線線都是一條線段或者多條線段組成的,只是在遊戲中我們看到只會是一氣呵成的線。既然有線段 那麼大家在初中的時候就知道線段有開始點和結束點。
然後我們在程式中就是想法求出這些線段的開始點和結束點就可以了。

有這個思想以後 我們就開始我們程式之旅 我上部分程式碼

[cpp] view plain copy
  1. void LLKAlgorithm::lineWay(cocos2d::CCArray* array,cocos2d::CCArray* htiarray,bool orishen){  
  2.         CustomSprite* hit1=(CustomSprite*)htiarray->objectAtIndex(0);// 取出第一個  
  3.         CustomSprite* hit2=(CustomSprite*)htiarray->objectAtIndex(1);// 取出第二個  
  4.   
  5.         CustomSprite* pEnd=NULL; // 結束點  
  6.         CustomSprite* pStar=NULL;// 開始點  
  7.         // 看看這兩個點 有沒有開始點 如果沒有 就把hit1 設定成 結束點 hit2 設定成 開始點   
  8.         if (hit1->getOriginal()==1){  
  9.                 pEnd=hit1;  
  10.                 pStar=hit2;  
  11.         }          
  12.         if (hit2->getOriginal()==1){  
  13.                 pEnd=hit2;  
  14.                 pStar=hit1;  
  15.         }          
  16.         if (pEnd==NULL){  
  17.                 pEnd=hit1;  
  18.                 pStar=hit2;  
  19.         }  
  20.         pEnd->setPath(0);  
  21.         if (orishen){                  
  22.                 int temppath=1;// 設定當前 直線的方向      
  23.                 if(pStar->getX()>pEnd->getX()){  
  24.                         temppath=3;  
  25.                 }                  
  26.           
  27.                 for (int i=0;i<array->count();i++){  
  28.                         CustomSprite* hitteim=(CustomSprite*) array->objectAtIndex(i);  
  29.                         if (hitteim!=pEnd){  
  30.                                 hitteim->setPath(temppath);  
  31.                         }  
  32.                 }  
  33.         }else {                  
  34.                 int temppath=2;// 設定當前 直線的方向  
  35.   
  36.                 if(pStar->getY()<pEnd->getY()){  
  37.                         temppath=4;  
  38.                 }  
  39.                 for (int i=0;i<array->count();i++){  
  40.                         CustomSprite* hitteim=(CustomSprite*) array->objectAtIndex(i);  
  41.                         if (hitteim!=pEnd){  
  42.                                 hitteim->setPath(temppath);  
  43.                         }  
  44.                 }  
  45.         }  
  46.   
  47. }  

通過上面的這個只是沒有拐角的連點連通的直線如何去畫,不過看過BOY 的演算法的人都知道,BOY 最後的步驟都是吧這些拐角都轉化成了 兩點直線連線的。所以來說就這個就可以了。

下面就說下道具的使用
連連看中最常用的道具, 查詢道具  炸彈 道具 重新排序道具。這三種最重要和最常用的道具,下面我就說下這三個道具的是如何通過演算法實現的,
第一個查詢道具
實現程式碼如下

[cpp] view plain copy
  1. void LLKGameLayer::seachCallBack(cocos2d::CCObject* psend){  
  2.         LLKmapLayer* lLKmapLayer=(LLKmapLayer*) this->getChildByTag(1);  
  3.         CCArray* llkarry= lLKmapLayer->getllkArray();  
  4.         CCArray* searcharr=CCArray::create();  
  5.         for(int i=0;i<llkarry->count();i++){  
  6.                 CustomSprite* custom=(CustomSprite*)llkarry->objectAtIndex(i);  
  7.                 if (custom->getIsEliminate()==false){  
  8.                         searcharr->addObject(custom);  
  9.                         for(int j=0;j<llkarry->count();j++){  
  10.                                 CustomSprite* custom2=(CustomSprite*)llkarry->objectAtIndex(j);  
  11.                                 if (custom2->getIsEliminate()==false){  
  12.                                         if (custom2!=custom){          
  13.                                                 if (custom->getIndex()==custom2->getIndex()){  
  14.                                                         searcharr->addObject(custom2);  
  15.                                                         break;  
  16.                                                 }  
  17.                                         }  
  18.                                 }  
  19.   
  20.   
  21.                         }  
  22.   
  23.                         if(searcharr->count()==2){  
  24.                                 CCArray* temp=LLKAlgorithm::algorithm(lLKmapLayer->gettotalArray(),searcharr);  
  25.                                 if (temp->count()>0){  
  26.                                         break;  
  27.                                 }else{  
  28.                                         LLKAlgorithm::removeAllArray(searcharr,false);  
  29.                                 }  
  30.   
  31.                         }  
  32.                 }  
  33.         }  
  34.   
  35.         if (searcharr->count()==2){  
  36.                 for(int i=0;i<searcharr->count();i++){  
  37.                         CustomSprite* temp=(CustomSprite*)searcharr->objectAtIndex(i);  
  38.                         temp->displayHitPic(1);  
  39.                 }  
  40.                 LLKAlgorithm::removeAllArray(searcharr,false);  
  41.         }  
  42.   
  43.   
  44. }  

上面的程式碼主要實現思路就是 把剩下的還沒消除的圖片 迴圈取出 兩張相同的圖片,然後通過我們上一章講解的演算法來判斷這兩章圖片是否相連。如果找到那麼就把這兩張圖片標示出來。  是不是很簡單 哈哈。


第二個演算法 
炸彈 這個我感覺是最簡單的了 
程式碼如下

[cpp] view plain copy
  1. void LLKGameLayer::boomCallBack(cocos2d::CCObject* psend){  
  2.         LLKmapLayer* lLKmapLayer=(LLKmapLayer*) this->getChildByTag(1);  
  3.         CCArray* llkarry= lLKmapLayer->getllkArray();  
  4.         CCArray* temparry=CCArray::create();  
  5.         for(int i=0;i<llkarry->count();i++){  
  6.                 CustomSprite* custom=(CustomSprite*)llkarry->objectAtIndex(i);  
  7.                 if (custom->getIsEliminate()==false){  
  8.                         temparry->addObject(custom);          
  9.                 }          
  10.         }  
  11.         if(temparry->count()>=2){  
  12.                 CustomSprite* custom=(CustomSprite*)temparry->randomObject();  
  13.                 CustomSprite* temp=NULL;  
  14.                 for(int i=0;i<temparry->count();i++){  
  15.                  temp=(CustomSprite*)temparry->objectAtIndex(i);  
  16.                   if(custom!=temp){  
  17.                           if(custom->getIndex()==temp->getIndex()){  
  18.                  break;  
  19.                           }  
  20.                   }  
  21.                 }  
  22.                 if(temp!=NULL){  
  23.                         temp->displayHitPic(3);  
  24.                 }  
  25.                 custom->displayHitPic(3);  
  26.         }  
  27.           
  28.   
  29.   
  30. }  

就是找到兩張一樣的圖片然後讓他們呢消失, 哈哈是不是很簡單。

第三個也就是重新排序 
這個演算法稍微複雜一點不過經過BOY 的手 哪裡還有那麼的難 廢話不多說上程式碼

[cpp] view plain copy
  1. void LLKGameLayer::restCallBack(cocos2d::CCObject* psed){  
  2.         // 處理方式 取出現在所有的 沒有被消除的 元素  
  3.         LLKmapLayer* lLKmapLayer=(LLKmapLayer*) this->getChildByTag(1);  
  4.         CCArray* llkarry= lLKmapLayer->getllkArray();  
  5.         CCArray* temparry=CCArray::create();  
  6.         for(int i=0;i<llkarry->count();i++){  
  7.                 CustomSprite* custom=(CustomSprite*)llkarry->objectAtIndex(i);  
  8.                 if (custom->getIsEliminate()==false){  
  9.                         custom->displayHitPic(2);  
  10.                         temparry->addObject(custom);          
  11.                 }          
  12.         }  
  13.         // 把剩下的元素 取出前半部分 然後隨機抽取出來一個 和 後半部分的元素呼喚位置   這樣就達到了重排的效果  
  14.         if (temparry->count()>=2){  
  15.          int ban=temparry->count()/2;  
  16.          CCArray* banarr=CCArray::create();  
  17.          for(int i=0;i<ban;i++){  
  18.                  banarr->addObject(temparry->objectAtIndex(i));  
  19.          }  
  20.          int temnum=0;  
  21.          for(int j=0;j<banarr->count();j++){           
  22.          CustomSprite* custom=(CustomSprite*)banarr->randomObject();  
  23.          banarr->removeObject(custom,false);  
  24.          j--;  
  25.          CustomSprite* custom2=(CustomSprite*) temparry->objectAtIndex(temnum+ban);  
  26.          CCPoint ccptem=custom->getPosition();  
  27.          int x=custom->getX();  
  28.          int y=custom->getY();  
  29.          custom->setPosition(custom2->getPosition());  
  30.          custom->setX(custom2->getX());  
  31.          custom->setY(custom2->getY());  
  32.          custom2->setPosition(ccptem);  
  33.          custom2->setX(x);  
  34.          custom2->setY(y);  
  35.          temnum++;  
  36.          }  
  37.   
  38.           
  39.         }  
  40.   
  41.   
  42.   
  43. }  

這個演算法的思路是這樣 把剩下的圖片 分成兩分,然後拿著第一份隨機抽取裡面的圖片和後面的元素兌換剩下的那半分兌換,座標 這樣就實現了重新重新整理,哈哈是不是很簡單,其實做了連連看的這個演算法的東西BOY 我深深的迷戀上演算法,以後我的教程中會對遊戲中常用的演算法進行講解。 以最通俗明瞭的辦法給大家講解關於演算法的東西。

    以上到此我們連連看的大部分就整理完了,大家可以把這個稍微改一下就可以做個自己的APP了。大家有疑問的可以加下面的這個群,或者在我的部落格給我留言。我會給大家講解的。

相關文章