• cocos2dx基础篇(25) 简单碰撞检测


    【3.x】

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

    【简单碰撞检测】

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

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

        (1)矩形与矩形

        (2)圆与圆

        (3)矩形与圆

    1、矩形与矩形

        1.1、提出问题

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

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

    wKiom1QFwuCS0a7IAAAnXuLCBYM543.jpg    wKioL1QFwuKQ7lK2AAAxXV3oZ_k652.jpg

    wKiom1QFwuCBbwtqAAAkm2811VU152.jpg    wKioL1QF0Ojz-1qnAAAh5ghkGt8517.jpg

        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未发生碰撞。

    wKioL1QF06Xgh6yhAABYDrSfp5g151.jpg    wKiom1QF06OQN5SrAABV2uYrcxg422.jpg

    wKioL1QF06Wzz1RTAABSejZG4UM796.jpg

        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未发生碰撞。

    wKioL1QF73nAZKVTAAA6sBYX2Rs665.jpg    wKiom1QF73eQvB-bAAA4x3hbNkA813.jpg

    wKioL1QF73miRhBnAAAxMVKieIM009.jpg        wKiom1QF73iyAqc2AABSjhSEcrE580.jpg

        3.2、解决方案

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

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

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

    wKioL1QF9iSgsP6CAADe5iZ6hoA754.jpg

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

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

    wKioL1QF-Q3BIL1ZAACBVOfs2_c233.jpg

        (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; 
    	}
    //
  • 相关阅读:
    SQL SERVER数据库优化相关资料
    京东面试题
    Jenkins部署资料
    [POI2005]Bank notes 【多重背包】
    [Usaco2004Feb]Cow Marathon 树的直径
    [ZJOI2008]骑士 基环树
    种树 反悔操作 【贪心】
    Poj2442 Sequence 贪心+堆优化
    洛谷div2【XR-4】歌唱比赛
    洛谷div2【XR-4】模拟赛
  • 原文地址:https://www.cnblogs.com/lmx282110xxx/p/10798704.html
Copyright © 2020-2023  润新知