2D游戏中圆形与矩形碰撞检测

来源:互联网 发布:zealerlive直播软件 编辑:程序博客网 时间:2024/04/23 14:50

【重点】:
       主要就是分两种情况:
       第一种:就是圆形与矩形边框的碰撞检测
                      检测Y轴圆心到矩中心的距离是否小于半径+矩形X轴1/2宽
                      检测X轴圆心到矩中心的距离是否小于半径+矩形Y轴1/2高
       第二种:就是特殊的矩形四个角检测
                       四个矩形顶角到圆心的距离是否小于半径

相信后面的大家就很容易理解
       这篇文章讲解一下基本的矩形和圆形之间的碰撞检测算法。上次我已经介绍过了矩形和矩形之间的碰撞检测,这次比上次麻烦那么一点。看图:

图上中间的红色矩形是碰撞的矩形,四个黑色圆形是代表要碰撞的圆形的四种不同位置。

二者碰撞最主要还是位于矩形的四个角。为了简洁,我还是运用上次的函数框架,虽然不是很方便,下面直接上代码:
Code ViewCopyPrint




    bool OverLap(RECT round, RECT rect)

{
int cr = (round.right - round.left)/2;
int cx = round.left + cr;
int cy = round.top  + cr;
int distanceX = abs(cx - rect.left - (rect.right-rect.left)/2);
int distanceY = abs(cy - rect.top - (rect.bottom-rect.top)/2);
if(distanceX > ((rect.right-rect.left)/2 + cr))returnfalse;
if(distanceY > ((rect.bottom-rect.top)/2 + cr))returnfalse;
if(distanceX <= (rect.right-rect.left)/2)returntrue;
if(distanceY <= (rect.bottom-rect.top)/2)returntrue;
int sq = (distanceX-(rect.right-rect.left)/2)*(distanceX-(rect.right-rect.left)/2) +
(distanceY-(rect.bottom-rect.top)/2)*(distanceY-(rect.bottom-rect.top)/2);
return (sq <= cr*cr);
}
应该很容易看懂,函数输入的是两个矩形,前者是画圆用的外接矩形,后者是碰撞的矩形。
代码简单的分析一下:
Code ViewCopyPrint
int cr = (round.right - round.left)/2;
int cx = round.left + cr;

int cy = round.top  + cr;

上面的几行代码是为了求出圆的半径和圆心。

Code ViewCopyPrint
int distanceX = abs(cx - rect.left - (rect.right-rect.left)/2);int distanceY = abs(cy - rect.top - (rect.bottom-rect.top)/2);
接下来的两行代码其实就是求圆心和矩形中心的距离。第一行是横坐标的距离,第二行是纵坐标的距离。
Code ViewCopyPrint
if(distanceX > ((rect.right-rect.left)/2 + cr))returnfalse;
if(distanceY > ((rect.bottom-rect.top)/2 + cr))returnfalse;
这两行是排除显而易见的情况,其实就是图上中间大的矩形外部的所有范围。第一句是表示圆形到矩形X坐标的距离大于二者半径的累加,排除图上的灰色线条两边的范围。第二句话排出的是两条蓝色线之外的范围,结合两者,正好剩余中间大的矩形范围。
Code ViewCopyPrint
if(distanceX <= (rect.right-rect.left)/2+r)returntrue;
if(distanceY <= (rect.bottom-rect.top)/2+r)returntrue;
接下来是显而易见的碰撞情况。这是为了检测矩形上下左右的碰撞。构成的图形是图上的粉色线条围成的十字形。这两条语句放在这里,是必须的。结合上边的两句话构成的是一个小的十字形,正好能检测矩形上下左右的碰撞情况。碰撞检测的形状就是这个样子:

最后两句代码:
Code ViewCopyPrint
int sq = (distanceX-(rect.right-rect.left)/2)*(distanceX-(rect.right-rect.left)/2) + (distanceY-(rect.bottom-rect.top)/2)*(distanceY-(rect.bottom-rect.top)/2);

return (sq <= cr*cr);

就是非常单纯的检测矩形的四个角落碰撞。方法就是检验矩形和圆形的距离的平方和与圆的半径的平方的大小关系。

如果上边的你不太懂,没有关系,我用这个算法写了一个DEMO,你可以下载测试,然后注释掉算法的每一条语句来检测,看看语句的作用,到时候就懂了。

DEMO截图:

原创粉丝点击