温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

cocos2dx基础篇(27)——简单碰撞检测

发布时间:2020-06-16 07:31:00 来源:网络 阅读:16959 作者:shahdza 栏目:开发技术

【唠叨】

    本节来讲讲简单的物理碰撞检测(非Box2D物理碰撞):矩形、圆之间的碰撞检测。


【3.x】

    将数学类 CCPointCCRect 改为v3.x版本的 Vec2Rect 就好了。




【简单碰撞检测】

    在一些游戏中经常会遇到碰撞检测的情况,如愤怒的小鸟飞出去后,是否与石头发生碰撞。

    虽然说有一个Box2D物理碰撞引擎,但是在这里还是需要掌握一下简单的碰撞检测方法。

    (1)矩形与矩形

    (2)圆与圆

    (3)矩形与圆


1、矩形与矩形


    1.1、提出问题

    问题:假设有两个矩形rect1,rect2,判断两矩是否碰撞相交(部分区域重叠)。

    如下四幅图中,图1、2、4发生碰撞,图3未发生碰撞。

cocos2dx基础篇(27)——简单碰撞检测    cocos2dx基础篇(27)——简单碰撞检测

cocos2dx基础篇(27)——简单碰撞检测    cocos2dx基础篇(27)——简单碰撞检测


    1.2、解决方案

    由图可知,判断方法只要计算一下两个矩形相交部分是否能够成一个小矩形。

    判断方法如下:(可用于计算相交部分的小矩形信息)

//
	bool collision_RectWithRect(CCRect rect1, CCRect rect2)
	{
	//计算相交部分的矩形
	//左下角坐标:( lx , ly )
	//右上角坐标:( rx , ry )
		float lx = max(rect1.getMinX() , rect2.getMinX() );
		float ly = max(rect1.getMinY() , rect2.getMinY() );

		float rx = min(rect1.getMaxX() , rect2.getMaxX() );
		float ry = min(rect1.getMaxY() , rect2.getMaxY() );

		//判断是否能构成小矩形
		if( lx > rx || ly > ry ) return false; //矩形不相交
		else                     return true;  //发生碰撞
	}
//


    当然也可以使用cocos2dx引擎中的CCRect类已经存在的一个判断矩形碰撞的函数。

//
	//返回bool。相交为true
	rect1.intersectsRect(rect2);
//
	
//	
	//intersectsRect()函数的源码如下:
	bool CCRect::intersectsRect(const CCRect& rect) const
	{
		return !(     getMaxX() < rect.getMinX() ||
				 rect.getMaxX() <      getMinX() ||
					  getMaxY() < rect.getMinY() ||
				 rect.getMaxY() <      getMinY());
	}
//


2、圆与圆

    2.1、提出问题

    问题:假设有两个圆circle1,circle2,判断两圆是否碰撞相交(部分区域重叠)。

    如下三幅图中,图1、2发生碰撞,图3未发生碰撞。

cocos2dx基础篇(27)——简单碰撞检测    cocos2dx基础篇(27)——简单碰撞检测

cocos2dx基础篇(27)——简单碰撞检测

    

    2.2、解决方案

    圆的碰撞检测比较简单,只要判断两圆心距离是否小于半径相加(r1+r2)即可。

    判断方法如下:

//
	bool collision_CircleWithCircle(CCPoint p1, float r1, CCPoint p2, float r2)
	{
	//计算圆心距离
		float dist = p1.getDistance(p2);

	//判断两圆是否相交
		return dist < (r1+r2) ;
	}
//


3、矩形与圆

    3.1、提出问题

    问题:假设有矩形rect、圆circle,判断矩形和圆是否碰撞相交(部分区域重叠)。

    如下四幅图中,图1、2、4发生碰撞,图3未发生碰撞。

cocos2dx基础篇(27)——简单碰撞检测    cocos2dx基础篇(27)——简单碰撞检测

cocos2dx基础篇(27)——简单碰撞检测        cocos2dx基础篇(27)——简单碰撞检测

    

    3.2、解决方案

    矩形和圆的判断比较复杂,请看以下分析。

    (1)首先,我们让圆在矩形外沿着矩形的边滚一圈,然后将圆心移动的轨迹连线,就可以得到一个圆角矩形。

    (2)如下图红色区域为圆角矩形,显然我们只要判断圆心是否在圆角矩形区域内部即可。

cocos2dx基础篇(27)——简单碰撞检测    

    (3)如果除去圆角矩形四个角上的4个四分之一圆的部分,仅仅让你判断圆心是否落在剩下的区域内,你应该能很快想出解决办法吧?

        只要判断圆心是否在两个矩形的任意其中之一的内部即可。

cocos2dx基础篇(27)——简单碰撞检测

    (4)然后再判断圆心是否在四个角上的四分之一圆的区域部分即可。

        显然,只要判断圆心与矩形的四个顶点的距离是否小于圆的半径即可。

    (5)综合上诉:(3)(4)的判断,即可得出圆是否矩形相交。


    判断方法如下:

//
	bool collision_RectWithCircle(CCRect rect, CCPoint p, float r)
	{
	//获取矩形信息
	//左下角坐标:( lx , ly )
	//右上角坐标:( rx , ry )
		float lx = rect.getMinX();
		float ly = rect.getMinY();
		float rx = rect.getMaxX();
		float ry = rect.getMaxY();

	//计算圆心到四个顶点的距离
		float d1 = p.getDistance( ccp(lx, ly) );
		float d2 = p.getDistance( ccp(lx, ry) );
		float d3 = p.getDistance( ccp(rx, ly) );
		float d4 = p.getDistance( ccp(rx, ry) );

	//判断是否碰撞
		//判断距离是否小于半径
		if( d1<r || d2<r || d3<r || d4<r ) return true;
		//是否在圆角矩形的,横向矩形内
		if( p.x > (lx-r) && p.x < (rx+r) && p.y > ly && p.y < ry ) return true;
		//是否在圆角矩形的,纵向矩形内
		if( p.x > lx && p.x < rx && p.y > (ly-r) && p.y < (ry+r) ) return true;

	//不发生碰撞
		return false; 
	}
//



向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI