太懒了,遇到这个问题好几天了,一直没写= =主要也没这个习惯
首先我们先找两张图片:
图A
和
图B
接下来是几种情况
第一种:两张图片不相交
第二种:两张图片相交,但是仅仅是透明部分相交
第三种:两张图片相交,有色区域相交
好了第三种就是真正的碰撞了。
我们的思路是对于某个点,若两张图片的透明度(ARGB里的A值)都不等于0就表示碰撞了。ps:RAGB里的A值为0即表示透明
接下来上代码
//预先读取图片数据
CCImage *img1=new CCImage();
img1->initWithImageFileThreadSafe("rocket.png");
Rocketdata=img1->getData();
CCImage *img2=new CCImage();
img2->initWithImageFileThreadSafe("rock_1.png");
Rockdata_1=img2->getData();
CCImage *img3=new CCImage();
img3->initWithImageFileThreadSafe("rock_2.png");
Rockdata_2=img3->getData();
//检测是否碰撞
int HelloWorld::isCollided(CCSprite *a,char* aPath,CCSprite *b,char* bPath){
//分别表示AB图的上下左右的坐标
float ABottom,ATop,ALeft,ARight;
float BBottom,BTop,BLeft,BRight;
CCSprite *aa=a;
CCSprite *bb=b;
CCSize Asize=aa->getContentSize();
CCSize Bsize=bb->getContentSize();
CCPoint Ap=aa->getPosition();
CCPoint Bp=bb->getPosition();
//cocos2dx的坐标系是以左下角为原点,而一般的坐标系是以左上角为原点
ATop=screenSize.height-Ap.y-Asize.height/2;
ABottom=screenSize.height-Ap.y+Asize.height/2;
ALeft=Ap.x-Asize.width/2;
ARight=Ap.x+Asize.width/2;
BTop=screenSize.height-Bp.y-Bsize.height/2;
BBottom=screenSize.height-Bp.y+Bsize.height/2;
BLeft=Bp.x-Bsize.width/2;
BRight=Bp.x+Bsize.width/2;
//两张图片没接触的情况,返回-1
if (ALeft > BRight || ATop > BBottom || BLeft > ARight || BTop > ABottom) {
return -1;
}
//相交矩形的上下左右的坐标以及长宽
float intersectLeft = ALeft > BLeft ? ALeft : BLeft;
float intersectTop = ATop >BTop ? ATop : BTop;
float intersectRight = ARight < BRight ? ARight : BRight;
float intersectBottom = ABottom < BBottom ? ABottom : BBottom;
float intersectWidth = intersectRight - intersectLeft;
float intersectHeight = intersectBottom - intersectTop;
//相交的矩形,在第一张第二张图的xy轴偏移量
float thisImageXOffset = intersectLeft - ALeft;
float thisImageYOffset = intersectTop - ATop;
float otherImageXOffset = intersectLeft - BLeft;
float otherImageYOffset = intersectTop - BTop;
//进行像素碰撞
int collisiontemp=doPixelCollision(int(Asize.height),(int)Asize.width,(int)Bsize.height,(int)Bsize.width,thisImageXOffset, thisImageYOffset, otherImageXOffset, otherImageYOffset, aPath, bPath, intersectWidth, intersectHeight);
return collisiontemp;
}
<pre name="code" class="cpp">int HelloWorld::doPixelCollision(int firstheight,int firstwidth,int secondheight,int secondwidth,float firstImageXOffset, float firstImageYOffset, float secondImageXOffset, float secondImageYOffset,
char* Apath, char* Bpath, float intersectWidth, float intersectHeight){
int Aheight,Awidth,Bheight,Bwidth;
Aheight=firstheight;
Awidth=firstwidth;
Bheight=secondheight;
Bwidth=secondwidth;
ccColor4B A={0,0,0,0};
ccColor4B B={0,0,0,0};
//事先读取好图片的像素值,不然每次都读太卡
unsigned int *Apixel=(unsigned int*)Rocketdata;
unsigned int *Bpixel;
if(Bpath=="rock_1.png"){
Bpixel=(unsigned int*)Rockdata_1;
}
else if(Bpath=="rock_2.png")
{
Bpixel=(unsigned int*)Rockdata_2;
}
int i,j,a,b;
//扫描相交区域是否存在一点AB图都不是透明的点,就表示相交
for(j=firstImageYOffset ,b=secondImageYOffset;j<firstImageYOffset+intersectHeight-1,b<secondImageYOffset+intersectHeight-1;j++,b++)
for(i=firstImageXOffset ,a=secondImageXOffset;i<firstImageXOffset+intersectWidth-1,a<secondImageXOffset+intersectWidth-1;i++,a++)
{
unsigned *Atemp,*Btemp;
Atemp=Apixel+j*Awidth+i;
//A.r = *Atemp & 0xff;
// A.g = (*Atemp >> 8) & 0xff;
// A.b = (*Atemp >> 16) & 0xff;
// A.a=(*Atemp >> 24) ;
Btemp=Bpixel+b*Bwidth+a;
// B.r = *Btemp & 0xff;
//B.g = (*Btemp >> 8) & 0xff;
// B.b = (*Btemp >> 16) & 0xff;
//B.a=(*Btemp >> 24) ;
//A和B都不透明,相交
if(((*Atemp >> 24)& 0xff)!=0&&((*Btemp >> 24)& 0xff)!=0)
{
//返回相交点
return j*firstwidth+i;
}
}
return -1;
}
上面的函数返回int型整数我是为了计算碰撞点。有什么问题就评论吧。有什么不足也请大神们指出。