cocos2d-x像素碰撞检测

本文介绍了在cocos2d-x中进行像素碰撞检测的方法,通过检查图片的透明度(A值)来判断是否发生碰撞,并提供了相关的代码示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

太懒了,遇到这个问题好几天了,一直没写= =主要也没这个习惯尴尬

首先我们先找两张图片


图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型整数我是为了计算碰撞点。有什么问题就评论吧。有什么不足也请大神们指出。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值