学习连连看 连接线之谜+道具的使用
下面讲解今天的重头戏,就是如何吧两个符合规则的图片链接起来。这个杂眼看起来很简单,不过BOY 也是费了很大的周折。
其实我发现连连第二个重要的算法就是这个了。不过BOY 想到了一个很简单的解决办法。下面就讲解一下。
大家看到这个连接的红线了,或许刚开始 可能看不出来这有什么规律,我也是研究和一下,看看希望怎么把这个算法告诉大家。
大家看到这个红线的时候 主要看那两个拐角的地方。其实在做的时候BOY 发现所有的线都是指向拐角处的。我画个图大家就明白了。
通过上一章的算法讲解我们很容易知道 那个拐角处的点是什么,如果对着一点不明白的先看看上一章连连看的算法。
这里有的朋友要问了,那没有拐角的怎么办呢,其实很好办,我之所以非要知道这个拐角是因为,这个拐角就是这个链接的结束。对已没有拐角的我就假设一个拐角,让其中的一条线指向他就可以了。简答一点说就是连连看中所有的连接线都是一条线段或者多条线段组成的,只是在游戏中我们看到只会是一气呵成的线。既然有线段 那么大家在初中的时候就知道线段有开始点和结束点。
然后我们在程序中就是想法求出这些线段的开始点和结束点就可以了。
有这个思想以后 我们就开始我们程序之旅 我上部分代码
- void LLKAlgorithm::lineWay(cocos2d::CCArray* array,cocos2d::CCArray* htiarray,bool orishen){
- CustomSprite* hit1=(CustomSprite*)htiarray->objectAtIndex(0);// 取出第一个
- CustomSprite* hit2=(CustomSprite*)htiarray->objectAtIndex(1);// 取出第二个
- CustomSprite* pEnd=NULL; // 结束点
- CustomSprite* pStar=NULL;// 开始点
- // 看看这两个点 有没有开始点 如果没有 就把hit1 设置成 结束点 hit2 设置成 开始点
- if (hit1->getOriginal()==1){
- pEnd=hit1;
- pStar=hit2;
- }
- if (hit2->getOriginal()==1){
- pEnd=hit2;
- pStar=hit1;
- }
- if (pEnd==NULL){
- pEnd=hit1;
- pStar=hit2;
- }
- pEnd->setPath(0);
- if (orishen){
- int temppath=1;// 设置当前 直线的方向
- if(pStar->getX()>pEnd->getX()){
- temppath=3;
- }
- for (int i=0;i<array->count();i++){
- CustomSprite* hitteim=(CustomSprite*) array->objectAtIndex(i);
- if (hitteim!=pEnd){
- hitteim->setPath(temppath);
- }
- }
- }else {
- int temppath=2;// 设置当前 直线的方向
- if(pStar->getY()<pEnd->getY()){
- temppath=4;
- }
- for (int i=0;i<array->count();i++){
- CustomSprite* hitteim=(CustomSprite*) array->objectAtIndex(i);
- if (hitteim!=pEnd){
- hitteim->setPath(temppath);
- }
- }
- }
- }
通过上面的这个只是没有拐角的连点连通的直线如何去画,不过看过BOY 的算法的人都知道,BOY 最后的步骤都是吧这些拐角都转化成了 两点直线连接的。所以来说就这个就可以了。
下面就说下道具的使用
连连看中最常用的道具, 查找道具 炸弹 道具 重新排序道具。这三种最重要和最常用的道具,下面我就说下这三个道具的是如何通过算法实现的,
第一个查找道具
实现代码如下
- void LLKGameLayer::seachCallBack(cocos2d::CCObject* psend){
- LLKmapLayer* lLKmapLayer=(LLKmapLayer*) this->getChildByTag(1);
- CCArray* llkarry= lLKmapLayer->getllkArray();
- CCArray* searcharr=CCArray::create();
- for(int i=0;i<llkarry->count();i++){
- CustomSprite* custom=(CustomSprite*)llkarry->objectAtIndex(i);
- if (custom->getIsEliminate()==false){
- searcharr->addObject(custom);
- for(int j=0;j<llkarry->count();j++){
- CustomSprite* custom2=(CustomSprite*)llkarry->objectAtIndex(j);
- if (custom2->getIsEliminate()==false){
- if (custom2!=custom){
- if (custom->getIndex()==custom2->getIndex()){
- searcharr->addObject(custom2);
- break;
- }
- }
- }
- }
- if(searcharr->count()==2){
- CCArray* temp=LLKAlgorithm::algorithm(lLKmapLayer->gettotalArray(),searcharr);
- if (temp->count()>0){
- break;
- }else{
- LLKAlgorithm::removeAllArray(searcharr,false);
- }
- }
- }
- }
- if (searcharr->count()==2){
- for(int i=0;i<searcharr->count();i++){
- CustomSprite* temp=(CustomSprite*)searcharr->objectAtIndex(i);
- temp->displayHitPic(1);
- }
- LLKAlgorithm::removeAllArray(searcharr,false);
- }
- }
上面的代码主要实现思路就是 把剩下的还没消除的图片 循环取出 两张相同的图片,然后通过我们上一章讲解的算法来判断这两章图片是否相连。如果找到那么就把这两张图片标示出来。 是不是很简单 哈哈。
第二个算法
炸弹 这个我感觉是最简单的了
代码如下
- void LLKGameLayer::boomCallBack(cocos2d::CCObject* psend){
- LLKmapLayer* lLKmapLayer=(LLKmapLayer*) this->getChildByTag(1);
- CCArray* llkarry= lLKmapLayer->getllkArray();
- CCArray* temparry=CCArray::create();
- for(int i=0;i<llkarry->count();i++){
- CustomSprite* custom=(CustomSprite*)llkarry->objectAtIndex(i);
- if (custom->getIsEliminate()==false){
- temparry->addObject(custom);
- }
- }
- if(temparry->count()>=2){
- CustomSprite* custom=(CustomSprite*)temparry->randomObject();
- CustomSprite* temp=NULL;
- for(int i=0;i<temparry->count();i++){
- temp=(CustomSprite*)temparry->objectAtIndex(i);
- if(custom!=temp){
- if(custom->getIndex()==temp->getIndex()){
- break;
- }
- }
- }
- if(temp!=NULL){
- temp->displayHitPic(3);
- }
- custom->displayHitPic(3);
- }
- }
就是找到两张一样的图片然后让他们呢消失, 哈哈是不是很简单。
第三个也就是重新排序
这个算法稍微复杂一点不过经过BOY 的手 哪里还有那么的难 废话不多说上代码
- void LLKGameLayer::restCallBack(cocos2d::CCObject* psed){
- // 处理方式 取出现在所有的 没有被消除的 元素
- LLKmapLayer* lLKmapLayer=(LLKmapLayer*) this->getChildByTag(1);
- CCArray* llkarry= lLKmapLayer->getllkArray();
- CCArray* temparry=CCArray::create();
- for(int i=0;i<llkarry->count();i++){
- CustomSprite* custom=(CustomSprite*)llkarry->objectAtIndex(i);
- if (custom->getIsEliminate()==false){
- custom->displayHitPic(2);
- temparry->addObject(custom);
- }
- }
- // 把剩下的元素 取出前半部分 然后随机抽取出来一个 和 后半部分的元素呼唤位置 这样就达到了重排的效果
- if (temparry->count()>=2){
- int ban=temparry->count()/2;
- CCArray* banarr=CCArray::create();
- for(int i=0;i<ban;i++){
- banarr->addObject(temparry->objectAtIndex(i));
- }
- int temnum=0;
- for(int j=0;j<banarr->count();j++){
- CustomSprite* custom=(CustomSprite*)banarr->randomObject();
- banarr->removeObject(custom,false);
- j--;
- CustomSprite* custom2=(CustomSprite*) temparry->objectAtIndex(temnum+ban);
- CCPoint ccptem=custom->getPosition();
- int x=custom->getX();
- int y=custom->getY();
- custom->setPosition(custom2->getPosition());
- custom->setX(custom2->getX());
- custom->setY(custom2->getY());
- custom2->setPosition(ccptem);
- custom2->setX(x);
- custom2->setY(y);
- temnum++;
- }
- }
- }
这个算法的思路是这样 把剩下的图片 分成两分,然后拿着第一份随机抽取里面的图片和后面的元素兑换剩下的那半分兑换,坐标 这样就实现了重新刷新,哈哈是不是很简单,其实做了连连看的这个算法的东西BOY 我深深的迷恋上算法,以后我的教程中会对游戏中常用的算法进行讲解。 以最通俗明了的办法给大家讲解关于算法的东西。
以上到此我们连连看的大部分就整理完了,大家可以把这个稍微改一下就可以做个自己的APP了。大家有疑问的可以加下面的这个群,或者在我的博客给我留言。我会给大家讲解的。