之前所用到的碰撞检测均为cocos提供的方法。
1、点与矩形碰撞
auto rec = tubeOn1->getBoundingbox();// 得要矩形区域
bool collision = rec.containsPoint(p);//p这个点是否在矩形区域内,返回一个bool型的值
2、矩形与矩形的碰撞
auto rec1 = bird->getBoundingbox();
// 得要一个矩形区域
auto rec2 = tubeOn1->getBoundingbox();// 得要另一个矩形区域
bool collision = rec2.intersectsRect(rec1);// rec1是否在rec2内
cocos封装好了,用起来自然是方便,但如果是不规则图形间的碰撞检测(常见的有圆形与矩形),要想精确实现碰撞就需要我们自己来写了。
首先我们先进去看看底层的实现,然后模仿着写下。
// cocos底层
矩形与矩形的碰撞检测函数
bool
Rect
::intersectsRect(
const
Rect
& rect)
const
{
return
!(
getMaxX
() < rect.
getMinX
() ||
rect.
getMaxX
() <
getMinX
() ||
getMaxY
() < rect.
getMinY
() ||
rect.
getMaxY
() <
getMinY
());
}
确实代码精简,无非是分为上下左右四个方向上的碰撞检测。其中先得到两个矩形框的中心点r1_p,r2_p(这就是我们要传的参数)如果
r1_p.x-r2_p.x>0&&abs(r1_p.y-r2_p.y)<
r1.height/2+r2.height/2
,则方向在右边,若
r1_p.x-r2_p.x<=r1.width/2+r2.width/2则碰撞,其他方向上的判定类似类似。
圆形与矩形碰撞,则需要将半径Radius传入作为圆形区域的高(宽)
//
碰撞检测
/*
bool
check3 =
collision
((birdPosition.
x
- birdSize.
width
/
3
), (birdPosition.
y
- birdSize.
height
/
3
), (birdPosition.
x
+ birdSize.
width
/
3
), (birdPosition.
y
+ birdSize.
height
/
3
),
columnPosition3.x, columnPosition3.y, (columnPosition3.x + columnSize3.width), (columnPosition3.y + columnSize3.height));
*/
static
bool
collision(
double
sMinX,
double
sMinY,
double
sMaxX,
double
sMaxY,
double
gMinX,
double
gMinY,
double
gMaxX,
double
gMaxY)
{
double
xOverlap =
0
;
double
yOverlap =
0
;
int
impacetArea =
0
;
if
(sMinX<=
gMaxX
&& sMinX>=gMinX && sMaxX>gMaxX)
{
xOverlap = abs(gMaxX - sMinX);
if
(sMaxY>
gMinY
&& sMaxY {
yOverlap = abs(gMinY - sMaxY);
}
else
if
(
sMinY
gMinY)
{
yOverlap = abs(gMaxY - sMinY);
}
}
else
if
(sMaxX>=gMinX && sMaxX<=gMaxX && sMinX<=gMinX)
{
xOverlap =
abs
(gMinX - sMaxX);
if
(sMaxY>gMinY && sMaxY {
yOverlap =
abs
(gMinY - sMaxY);
}
else
if
(sMinYgMinY)
{
yOverlap =
abs
(gMaxY - sMinY);
}
}
else
if
(sMaxX<=gMaxX && sMaxX>=gMinX && sMinX>=gMinX && sMaxX>=gMinX)
{
xOverlap =
abs
(sMaxX - sMinX);
if
(sMaxY>gMinY && sMaxY {
yOverlap =
abs
(gMinY - sMaxY);
}
else
if
(sMinYgMinY)
{
yOverlap =
abs
(gMaxY - sMinY);
}
}
impacetArea = xOverlap * yOverlap;
if
(impacetArea>
0
)
{
return
true
;
}
return
false
;
}
1、圆形与矩形的碰撞检测
函数ComputeCollision,当相对距离小于圆形半径的时候为碰撞。
参数介绍(w:矩形的宽,h:矩形的高,r:圆形半径,rx:圆形中心与矩形中心相对坐标X,ry:圆形中心与矩形中心相对坐标Y)
function ComputeCollision(w, h, r, rx, ry) {
var dx = Math.min(rx, w * 0.5);
var dx1 = Math.max(dx, -w * 0.5);
var dy = Math.min(ry, h * 0.5);
var dy1 = Math.max(dy, -h * 0.5);
return (dx1 - rx) * (dx1 - rx) + (dy1 - ry) * (dy1 - ry) <= r * r;
}
2、圆形坐标中心位置和矩形坐标中心位置
圆形坐标指鼠标的位置
修正圆形的位置,让鼠标在圆心的中心位置
//圆心坐标
var radiusPosX = parseInt((event.clientX || event.x));
var radiusPosY = parseInt((event.clientY || event.y));
event = event || window.event;
//让鼠标在圆心的位置
circle.style.left = parseInt(radiusPosX - radius) + "px";
circle.style.top = parseInt(radiusPosY - radius) + "px";
矩形的长宽
矩形的中心位置是(相对距左+宽度,相对距顶+高度)。
//
矩形的长宽
var rectW =
rect.clientWidth;
var rectH =
rect.clientHeight;
//
矩形中心坐标
var rectPosX = parseInt(rect.offsetLeft) + rectW / 2
;
var rectPosY = parseInt(rect.offsetTop) + rectH / 2;