版本:cocoscreator 3.8.2

 

目录

一 矩形碰撞

二 圆形碰撞

三 圆形和矩形碰撞

四 其它更多碰撞检测

 

游戏中常用的碰撞检测

1. 角色砍一刀,检测敌方是否在攻击范围内。

2. 子弹飞行时,是否击中角色。

3. 角色移动时,和障碍物、地图边缘的碰撞检测,碰撞则不能行走。

4. 角色AOE法术,检测敌方是否在法术攻击范围内。

5. 等等

 

一 矩形碰撞

AABB,Axis-Aligned Bounding Box,轴对齐包围盒,判断投影是否重叠方法来检测碰撞,AABB表示没有旋转的矩形。

 

cocos提供的碰撞检测方法,intersection-2d.ts:

/**
 * @en Test rect and rect
 * @zh 测试矩形与矩形是否相交
 */
function rectRect (a: Rect, b: Rect): boolean {
    // jshint camelcase:false

    const a_min_x = a.x;
    const a_min_y = a.y;
    const a_max_x = a.x + a.width;
    const a_max_y = a.y + a.height;

    const b_min_x = b.x;
    const b_min_y = b.y;
    const b_max_x = b.x + b.width;
    const b_max_y = b.y + b.height;

    return a_min_x <= b_max_x
        && a_max_x >= b_min_x
        && a_min_y <= b_max_y
        && a_max_y >= b_min_y;
}

 

判断红色和蓝色Node是否碰撞,下图是有碰撞的,输出为true。

image

const isHit: boolean = Intersection2D.rectRect(this.red.getComponent(UITransform).getBoundingBox(), this.blue.getComponent(UITransform).getBoundingBox());
console.log(isHit);  //true

 

其中getBoundingBox()获取的Rect,值(x,y,width,height)中的x,y是矩形左下角的坐标位置。

this.red.getComponent(UITransform).getBoundingBox()

  

该方法不能检查旋转的图形,如下图,红色旋转了45°,碰撞检测仍然输出为true,这是不对的。

image

 

带旋转的矩形OBB,Oriented Bounding Box,有向包围盒。cocos没有提供OBB的碰撞检测,需要自己实现。

最可靠方法是分离轴定理(SAT),具体实现可用AI,挺复杂的,平时也用不着旋转的矩形碰撞检测。

 

总结:

1. 不带旋转的矩形叫轴对齐包围盒AABB,碰撞检测可直接使用cocos提供方法。

2. 带旋转的矩形叫有向包围盒OOB,碰撞检测得自己实现。

3. 碰撞检测方法不受锚点影响,例如(0.5,0.5)或(0,0)都能正确检测。

4.矩形碰撞常用于攻击范围、障碍物碰撞检测等。

 

二 圆形碰撞

圆形之间检测主要判断圆心距离是否超过了两个圆的半径之和。

 

cocos提供的圆形碰撞检测,intersection-2d.ts:

/**
 * @en Test circle and circle
 * @zh 测试圆形与圆形是否相交
 */
function circleCircle (c1p: Readonly<Vec2>, c1r: number, c2p: Readonly<Vec2>, c2r: number): boolean {
    const distance = Vec2.distance(c1p, c2p);
    return distance < (c1r + c2r);
}

  

如下图两圆,半径分别是25和50,检测结果是true。

image

 

const isHit: boolean = Intersection2D.circleCircle(v2(this.red.position.x, this.red.position.y), 25, v2(this.blue.position.x, this.blue.position.y), 50);
console.log(isHit);  //true

  

总结:

1. 圆形碰撞常用于飞行射击游戏中,子弹和飞机的碰撞。

 

三 圆形和矩形碰撞

找到离圆心最近的矩形顶点,判断圆心和顶点的距离小于圆半径,则碰撞。

 

cocos提供的方法,intersection-2d.ts:

/**
 * @en Test rect and circle
 * @zh 测试矩形与圆形是否相交
 */
function rectCircle (rect: Rect, cp: Readonly<Vec2>, cr: number): boolean {
    const cx = cp.x;
    const cy = cp.y;

    const rx = rect.x;
    const ry = rect.y;
    const rw = rect.width;
    const rh = rect.height;

    // temporary variables to set edges for testing
    let testX = cx;
    let testY = cy;

    // which edge is closest?
    if (cx < rx) testX = rx;      // test left edge
    else if (cx > rx + rw) testX = rx + rw;   // right edge
    if (cy < ry) testY = ry;      // top edge
    else if (cy > ry + rh) testY = ry + rh;   // bottom edge

    // get distance from closest edges
    const distX = cx - testX;
    const distY = cy - testY;
    const distance = Math.sqrt((distX * distX) + (distY * distY));

    // if the distance is less than the radius, collision!
    if (distance <= cr) {
        return true;
    }
    return false;
}

  

red是矩形,blue是半径50的圆形,检测结果是true。

image

 

const isHit: boolean = Intersection2D.rectCircle(this.red.getComponent(UITransform).getBoundingBox(), v2(this.blue.position.x, this.blue.position.y), 50);
console.log(isHit);  //true

  

四 其它更多的碰撞检测

线段与线段

线段与矩形

线段与多边形

矩形与多边形

多边形与多边形

多边形与圆形

点是否在一个多边形中

点到直线距离

这些都可以在cocos源码intersection-2d.ts中找到。

 

posted on 2025-08-18 16:06  gamedaybyday  阅读(120)  评论(0)    收藏  举报