cocos2d-x的初步学习二十七之连连看三
发布日期:2022-02-08 18:03:29 浏览次数:47 分类:技术文章

本文共 12778 字,大约阅读时间需要 42 分钟。

接下来,我们将完成剩下的游戏界面部分。连连看我们可以看做是一个m行乘以n列的一个矩行,其中我们规定0为空的,其余数字可以看作是图片的引用id,通过这个id,我们可以直接找到这个图片,有了图片,我们就可以初始化出这个对应的精灵。然后通过touch事件判断出是否选中或是没选中这个精灵,然后通过相应的算法,算出所选两个精灵对象是否是一样的,并且符合我们的游戏规则,符合就消掉,不符合再重新选取。。。。。。

00001000200003

10000300000002

00040000040000

OK,,我们先新建一个类,叫MapLayer,这个类主要是游戏地图层的部分

//地图层class MapLayer :public cocos2d::CCLayerColor{    public:        virtual bool init();            CREATE_FUNC(MapLayer);    void initUI(void);        void initData(void);            ~MapLayer();        private:        };
上面部分就是新建一个类,定义一些初始化的函数。对于数据部分,你可以存储在一个一维数组里,当然也可以存储到文件中,只要你能获取到数据,那你怎么存都OK的~~~

这里,我们把数据存到一个plist文件里,plist可以看作是一个xml,我们新建一个plist,叫levelinfo.plist

我们定义第一关001,里面有total_x,列数,total_y,行数,也就是上面我们定义了一个5*9的一个矩形,array里面存了图片对应的id,0表示无,没有。

OK。。接下来,我们来解析这个xml,,代码如下

//读取plist数据文件    const char *plistPath=CCFileUtils::sharedFileUtils()->fullPathFromRelativeFile("levelinfo.plist","levelinfo.plist");        CCDictionary *plistDic=CCDictionary::createWithContentsOfFile(plistPath);            CCDictionary *levelDic=dynamic_cast
(plistDic->objectForKey("001")); CCString *xstring=dynamic_cast
(levelDic->objectForKey("total_x")); total_x=xstring->intValue(); CCString *ystring=dynamic_cast
(levelDic->objectForKey("total_y")); total_y=ystring->intValue(); CCArray *array=CCArray::create(); array=dynamic_cast
(levelDic->objectForKey("imageidarr"));
这样,我们就读取到plist里相应的数据,接下来,我们定义一个类,叫MapNode类,它就提供两个属性,order跟id,代码如下

class MapNode :public cocos2d::CCObject{public:        //序号    int order;    //图片的id    int imgid;};
接下来,我们对把plist的array里的数据取出来,然后赋值给MapNode的imgid属性,代码如下

mapArray=CCArray::create();        mapArray->retain();            CCArray *array2=CCArray::create();        //种子    srandom((unsigned int)time(NULL));            for (int i=0; i<(total_x-1)*(total_y-1); i++)    {                MapNode *node=new MapNode();        node->autorelease();        //产生唯一的orderid        node->order=(int)(CCRANDOM_0_1()*INT_MAX)%(int)(CCRANDOM_0_1()*INT_MAX);                CCString *idString=(CCString *)(array->objectAtIndex(i));                node->imgid=idString->intValue();        array2->addObject(node);            }        //排序    qsort(array2->data->arr, array2->data->num, sizeof(long),compare);            for (int x=0; x
autorelease(); node->order=0; node->imgid=0; mapArray->addObject(node); }else { int i = (y - 1) * (total_x - 1) + x - 1; mapArray->addObject(array2->objectAtIndex(i)); } } }
mapArray里存的都是经过排序后的mapnode,c排序函数

void qsort(void *, size_t, size_t,int (*)(const void *, const void *));第一个参数是数组头部首地址,第二个参数数组长度,第三个是数组每个元素大小size,第四个是一个int型函数指针,

//排序比较int compare(const void *a,const void *b){    MapNode *node1=(MapNode *)a;        MapNode *node2=(MapNode *)b;    if (node1->order>node2->order)    {                return 1;            }    else if (node1->order==node2->order)    {                return 0;            }    else    {        return -1;        }}
OK,接下来,我们来布局我们的图片sprite,代码如下

//布局sprite    for (int y = 0; y < total_y; ++y)    {        		for (int x = 0; x < total_x; ++x)        {                        int index=y*total_x+x;                        if (this->imageFilename(index))            {                                CCSprite *sprite=CCSprite::createWithSpriteFrameName(this->imageFilename(index)->getCString());                                sprite->setScale(1.0);                sprite->setPosition(ccp(OFFSET_X * x + (SIZE_W / 2) + SIZE_W * x, OFFSET_Y * y + (SIZE_H / 2) + SIZE_H * y));                                this->addChild(sprite, 1, TAG_START_SPRITE+index);                                            }                                }                    }
//获取图片CCString* MapLayer::imageFilename(int index){    int n=((MapNode *)(mapArray->objectAtIndex(index)))->imgid;       // CCLOG("n------:%d",index);    if (n>=1 && n<=20)    {                        return CCString::createWithFormat("%d.png",n);                    }    else    {                    return NULL;        }    }
我们运行下,看下效果

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

接下来,我们加入触摸事件,代码如下

MapLayer.h中加入

virtual bool ccTouchBegan(cocos2d::CCTouch *pTouch, cocos2d::CCEvent *pEvent);    virtual void ccTouchEnded(cocos2d::CCTouch *pTouch, cocos2d::CCEvent *pEvent);

MapLayer.cpp中加入

//添加touch监听    CCDirector::sharedDirector()->getTouchDispatcher()->addTargetedDelegate(this, 1, true);

//bool MapLayer::ccTouchBegan(cocos2d::CCTouch *pTouch, cocos2d::CCEvent *pEvent){        return true;}//void MapLayer::ccTouchEnded(cocos2d::CCTouch *pTouch, cocos2d::CCEvent *pEvent){    }
我们将在touchend里处理事件,我们获取手指触摸点的坐标,然后把它转换成本地坐标,不然获取的坐标是整个下层的坐标,再把本地坐标转换成地图坐标,就像坦克大战里的,比如(1,2)之类的,看代码

//bool MapLayer::ccTouchBegan(cocos2d::CCTouch *pTouch, cocos2d::CCEvent *pEvent){    CCPoint location = CCDirector::sharedDirector()->convertToGL(pTouch->getLocationInView());    //在这个层区域内返回true    if (this->boundingBox().containsPoint(location))    {                        return true;                    }        //否则返回false,阻止接下来的touch函数    return false;}//void MapLayer::ccTouchEnded(cocos2d::CCTouch *pTouch, cocos2d::CCEvent *pEvent){    CCPoint location = CCDirector::sharedDirector()->convertToGL(pTouch->getLocationInView());	location = this->convertToNodeSpace(location);        //location=CCPointMake(location.x, location.y-40);        location=this->pointOfView(location);            //  CCLOG("x:%f",location.x);    //  CCLOG("y:%f",location.y);        }
//屏幕坐标转换成地图坐标CCPoint MapLayer::pointOfView(cocos2d::CCPoint point){    int x = -1; 	int y = -1; 	if (point.x > 0 && point.x < total_x * SIZE_W + OFFSET_X * (total_x-1)) 		x = (point.x ) / (SIZE_W+OFFSET_X); 	if (point.y > 0 && point.y < (total_y-1)* OFFSET_Y + total_y * SIZE_H ) 		y = (point.y) / (SIZE_H+OFFSET_Y);      	return CCPoint(x, y); }
OK。。。。接下来,我们会把剩下的一些算法,判断函数全部写下来,大家直接看代码吧

//是否在有效范围内bool MapLayer::isValiableNode(cocos2d::CCPoint point){	return point.x >= 0 && point.x < total_x && point.y >= 0 && point.y < total_y;}//是否是空的坐标点bool MapLayer::isEmptyNode(cocos2d::CCPoint point){    int index=this->indexFromPoint(point);            MapNode *node=(MapNode *)mapArray->objectAtIndex(index);            return (node->imgid==0);    }//每个sprite的indexint MapLayer::indexFromPoint(cocos2d::CCPoint point){    return point.y * total_x + point.x;    }//是否是相同的点bool MapLayer::isSamePoints(cocos2d::CCPoint p1, cocos2d::CCPoint p2){	return (p1.x == p2.x && p1.y == p2.y);}//清除void MapLayer::clearNode(cocos2d::CCPoint point){    int index=this->indexFromPoint(point);            MapNode *node=(MapNode *)mapArray->objectAtIndex(index);    node->imgid=0;}//判断两个是否可以消除bool MapLayer::canClearTwo(cocos2d::CCPoint pointpre, cocos2d::CCPoint pointcurrent){	bool bMatch = false;	int pre = this->indexFromPoint(pointpre);	int current = this->indexFromPoint(pointcurrent);	int p = ((MapNode *)(mapArray->objectAtIndex(pre)))->imgid;	int c = ((MapNode *)(mapArray->objectAtIndex(current)))->imgid;	    if (p == c && this->match(pointcurrent, pointpre)) {		bMatch = true;	}		return bMatch;}//放大缩小动画void MapLayer::scaleAnimation(cocos2d::CCSprite* sprite){        CCScaleTo *ac1=CCScaleTo::create(0.07f, 1.0);    CCScaleTo *ac2=CCScaleTo::create(0.07f, 0.9);    CCScaleTo *ac3=CCScaleTo::create(0.07f, 1.0);    CCSequence *seq=CCSequence::create(ac1,ac2,ac3,NULL);    sprite->runAction(seq);        }
//三种匹配算法//一直线bool MapLayer::match_direct(cocos2d::CCPoint a, cocos2d::CCPoint b){	if (!(a.x == b.x || a.y == b.y)) {		return false;	}		int i;	bool match_x = false;	if(a.x == b.x) {		match_x = true;		if(a.y > b.y) {			for(i = a.y - 1; i > b.y; --i) {				CCPoint point = CCPointMake(a.x, i);                if(!this->isValiableNode(point) || !this->isEmptyNode(point)){					match_x = false;				}			}		}		if(b.y > a.y) {			for(i = b.y - 1; i > a.y; --i) {				CCPoint point = CCPointMake(a.x, i);				if(!this->isValiableNode(point) || !this->isEmptyNode(point)) {					match_x = false;				}			}		}	}		bool match_y = false;	if(a.y == b.y) {		match_y = true;		if(a.x > b.x) {			for(i = a.x - 1; i > b.x; --i) {				CCPoint point = CCPointMake(i, a.y);				if(!this->isValiableNode(point) || !this->isEmptyNode(point)) {					match_y = false;				}			}		}		if(b.x > a.x) {			for(i = b.x - 1; i > a.x; --i) {				CCPoint point = CCPointMake(i, a.y);				if(!this->isValiableNode(point) || !this->isEmptyNode(point)) {					match_y = false;				}			}		}	}		return match_x || match_y;}//一个拐点的bool MapLayer::match_one_corner(cocos2d::CCPoint a, cocos2d::CCPoint b){	CCPoint point = CCPointMake(b.x, a.y);        if( this->isValiableNode(point) && this->isEmptyNode(point) && this->match_direct(a, point) && this->match_direct(b, point)){        return true;    }		point = CCPointMake(a.x, b.y);	if( this->isValiableNode(point) && this->isEmptyNode(point) && this->match_direct(a, point) && this->match_direct(b, point)){        return true;    }		return false;}//两个拐点的bool MapLayer::match_two_corner(cocos2d::CCPoint a, cocos2d::CCPoint b){	for(int i = a.x - 1; i >= 0; --i) {		CCPoint point = CCPointMake(i, a.y);        if (!this->isValiableNode(point) || !this->isEmptyNode(point)) {            break;        } else {            if (this->match_one_corner(point, b)) {                return true;            }        }	}		for(int i = a.x + 1; i < total_x; ++i) {		CCPoint point = CCPointMake(i, a.y);        if (!this->isValiableNode(point) || !this->isEmptyNode(point)) {            break;        } else {            if (this->match_one_corner(point, b)) {                return true;            }        }	}		for(int i = a.y - 1; i >= 0; --i) {		CCPoint point = CCPointMake(a.x ,i);		if (!this->isValiableNode(point) || !this->isEmptyNode(point)) {            break;        } else {            if (this->match_one_corner(point, b)) {                return true;            }        }	}		for(int i = a.y + 1; i < total_y; ++i) {		CCPoint point = CCPointMake(a.x ,i);		if (!this->isValiableNode(point) || !this->isEmptyNode(point)) {            break;        } else {            if (this->match_one_corner(point, b)) {                return true;            }        }	}		return false;}bool MapLayer::match(cocos2d::CCPoint a,cocos2d::CCPoint b){    if (this->match_direct(a, b)) {        return true;    }    if (this->match_one_corner(a, b)) {        return true;    }    if (this->match_two_corner(a, b)) {        return true;    }		return false;}
重新写touch事件

//bool MapLayer::ccTouchBegan(cocos2d::CCTouch *pTouch, cocos2d::CCEvent *pEvent){    CCPoint location = CCDirector::sharedDirector()->convertToGL(pTouch->getLocationInView());    //在这个层区域内返回true    if (this->boundingBox().containsPoint(location))    {                        return true;                    }        //否则返回false,阻止接下来的touch函数    return false;}//void MapLayer::ccTouchEnded(cocos2d::CCTouch *pTouch, cocos2d::CCEvent *pEvent){    CCPoint location = CCDirector::sharedDirector()->convertToGL(pTouch->getLocationInView());	location = this->convertToNodeSpace(location);        //location=CCPointMake(location.x, location.y-40);        location=this->pointOfView(location);              CCLOG("x:%f",location.x);      CCLOG("y:%f",location.y);    if (this->isValiableNode(location)==false)    {        return;    }        if (this->isEmptyNode(location))    {        return;    }        SimpleAudioEngine::sharedEngine()->playEffect("12.wav");                if (this->isSamePoints(location, prePoint))    {        return;    }        //点击当前精灵    CCSprite *spritecurrent=(CCSprite *)this->getChildByTag(TAG_START_SPRITE+this->indexFromPoint(location));    spritecurrent->setScale(1.3);    CCLOG("%d",this->indexFromPoint(location));        if (this->isValiableNode(prePoint))    {            //前一个         CCSprite *spritepre=(CCSprite *)this->getChildByTag(TAG_START_SPRITE+this->indexFromPoint(prePoint));                if (this->canClearTwo(prePoint, location))        {                        SimpleAudioEngine::sharedEngine()->playEffect("4.wav");            this->clearNode(location);            this->clearNode(prePoint);                                    spritecurrent->setVisible(false);            spritepre->setVisible(false);                                }        else        {                            spritepre->setScale(0.9);                                this->scaleAnimation(spritepre);                }                            }                    prePoint=location;        }
运行,效果如下

选中的时候,放大精灵~~~~

~~~~~这里时间有限,下一篇的文章将探讨一些自动消除,还有用粒子效果来实现消除时的动画等,还有一些其他问题~~~

转载地址:https://blog.csdn.net/kuloveyouwei/article/details/13004465 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:cocos2d-x的初步学习二十五之连连看一
下一篇:cocos2d-x的初步学习二十六之连连看二

发表评论

最新留言

很好
[***.229.124.182]2024年03月21日 08时54分01秒

关于作者

    喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!

推荐文章

hp-ux 查看系统负载_Linux性能调优 | 平均负载的理解和分析 2019-04-21
elementui的tree组件页面显示不出数据_vue路由及组件 2019-04-21
android hook sensor数据_最近,又有人在谈论Android的前景了!深入解析趋势及必备技术点... 2019-04-21
python 动态tabel的数据爬取_使用requests爬取python岗位招聘数据 2019-04-21
input js number 整数_JS基础简单小结(1) 2019-04-21
二阶差分预测后数据还原公式_xgboost系列丨xgboost原理及公式推导 2019-04-21
docker mysql服务启动失败_docker中mysql初始化及启动失败问题解决方案 2019-04-21
mysql 阿里云 添加磁盘空间_rds mysql磁盘空间包含 2019-04-21
mysql 1364 hy000_mysql SQL Error: 1364, SQLState: HY000 保存错误 2019-04-21
mysqli拓展还能用mysql_最近在学习php,其中使用了MYSQLi扩展,注意是MYSQLi不是MYSQL(因PHP7已经不支持MYSQL扩展了)。... 2019-04-21
java中gui_java中GUI是什么意思?详细图解 2019-04-21
java iso 8601_如何在iOS上获得ISO 8601日期? 2019-04-21
windows8怎么下载python_win8怎么安装python 2019-04-21
linux猜数字程序,用linux实现猜数字小游戏源码 2019-04-21
linux下堆栈溢出实例,堆栈溢出在Linux上沉默? 2019-04-21
python创建nc文件_工具箱第2期 用python玩转NC 2019-04-21
拆分文件_文件拆分与合并 2019-04-21
开发优势_小程序开发优势好处有哪些 2019-04-21
4光影补丁_我的世界seus光影包 2019-04-21
aria手机下载_Aria2App 2019-04-21