声 明本教程仅用于初学cocos2dx同学使用,内容由本人(孤狼)学习过程中笔记编写,本教程使用cocos2dx版本为2.1.4。本教程内容可以自由转载,但必须同时附带本声明,或注明出处。gl.paea.cn版权所有。
大家好,欢迎回到“和屌丝一起学cocos2dx”系列教程。上节我们说到了“多点触控”,不知道大家测试没测试自己的爪机支持几个点呢?这节我们要说一个在游戏中会经常遇到的东东,碰撞。
【一】:这个是啥玩意
碰撞就是当两张图片接触的时候出发的事件,比如你的2个精灵,一个人一个子弹,如果子弹接触到人了,是不是改促发一些事件了呢?比如掉血,over等等。
【二】:函数
矩形:
intersectsRect(CCRect);
这个函数是CCRect自带的函数,用于判断当前对象是不是与目标对象接触。返回true为接触。
containsPoint(CCPoint);
这个函数也是CCRect自带的函数,用于判断当前对象是不是与目标点接触。返回true为接触。
【三】:示例
1.新建项目Rectbong
2.加载2张图片
Rectbong.h
写上更新回调函数
void update(float tmd);
写上圆形碰撞判断函数
bool isbong(CCPoint p1,float r1,CCPoint p2,float r2);
Rectbong.cpp
1.在初始化函数里
//用矩形图片创建2个精灵
CCSize mysize=CCDirector::sharedDirector()->getWinSize();
CCSprite* sp1 = CCSprite::create("a.png");
sp1->setPosition(ccp(100, mysize.height/2));
this->addChild(sp1, 0,1);
CCSprite* sp2 = CCSprite::create("b.png");
sp2->setPosition(ccp(mysize.width-100, mysize.height/2));
this->addChild(sp2, 0,2);
//在做个显示
CCLabelTTF * ttf=CCLabelTTF::create("none","Arial",20);
ttf->setPosition(ccp(mysize.width/2,mysize.height-50));
this->addChild(ttf,0,3);
//做个移动
sp1->runAction(CCMoveTo::create(5,ccp(mysize.width-190,mysize.height/2)));
//开启更新
scheduleUpdate();
2.实现更新函数
void Rectbong::update(float tmd){
CCSprite * sp1=(CCSprite *)this->getChildByTag(1);
CCSprite * sp2=(CCSprite *)this->getChildByTag(2);
CCLabelTTF * ttf=(CCLabelTTF *)this->getChildByTag(3);
//矩形碰撞
//if(sp1->boundingBox().intersectsRect(sp2->boundingBox())){
//ttf->setString("bong!!!!");
//}else{
//ttf->setString("none");
//}
//圆形碰撞
if(this->isbong(sp1->getPosition(),20,sp2->getPosition(),20)){
ttf->setString("bong!!!!");
}else{
ttf->setString("none");
}
}
3.实现圆形碰撞函数
bool Rectbong::isbong(CCPoint p1,float r1,CCPoint p2,float r2){
//用三角型定理来计算圆心距,然后与半径和对比
if(sqrt(pow(p1.x-p2.x,2)+pow(p1.y-p2.y,2))>r1+r2){
return false;
}else{
return true;
}
}
好了,我们先来看下效果。
ok实现了。
【四】:问题
这里,我们看到,我们的png图片,边缘接触,于是系统提示接触了,可是如果A是子弹,B是人,这个时候就判断人死了,好像不太合理,我们能不能让里面的小矩形接触才出发判断呢?怎么才能更精确呢?
这里我们有几种解决方案。
1.采用像素判断方式
2.替换精确图片
3.采用圆形判断
第一种方式,确实要精确的多,只有存在像素接触的时候才会判断,但是,像素判断要不停的判断每个像素有没有接触,非常消耗CPU资源。所以我们一般不选用。
第二种方式,就是我们要把图尽可能做细,这样就能很好的判断了。
第三种方式,就是有我们自己决定精确度,相对来说更好一点。
那么我们来看看圆形碰撞的效果
(接触了,但是没有到达半径和,所以不会提示)
(当达到半径和的时候,开始提示。)
最后还是要和大家说一下,我这里是把判断函数放在了更新函数里,你们可以放在其他地方哦,比如触屏事件里。嘿嘿。