碰撞检测用于判断两个或多个物体是否发生接触,在前端开发中有着广泛的应用场景,比如小游戏中的角色与障碍物碰撞、拖拽元素与边界碰撞、页面元素的交互触发等。不同的物体形状对应不同的检测算法,下面介绍几种常用的JavaScript碰撞检测实现方式。

矩形碰撞检测算法
矩形碰撞是最常用的碰撞检测场景,适用于大部分DOM元素、矩形游戏角色的检测。核心原理是判断两个矩形的投影是否在x轴和y轴上都有重叠,如果两个轴都存在重叠则说明发生了碰撞。
假设两个矩形的属性分别为:矩形A的左上角坐标(x1,y1),宽度w1,高度h1;矩形B的左上角坐标(x2,y2),宽度w2,高度h2。碰撞的判断条件为:
- 矩形A的右边界大于矩形B的左边界:x1 + w1 > x2
- 矩形A的左边界小于矩形B的右边界:x1 < x2 + w2
- 矩形A的下边界大于矩形B的上边界:y1 + h1 > y2
- 矩形A的上边界小于矩形B的下边界:y1 < y2 + h2
对应的JavaScript实现代码如下:
/**
* 矩形碰撞检测函数
* @param {Object} rect1 矩形1 {x, y, width, height}
* @param {Object} rect2 矩形2 {x, y, width, height}
* @returns {boolean} 是否发生碰撞
*/
function checkRectCollision(rect1, rect2) {
// 判断x轴投影是否重叠
const xOverlap = rect1.x + rect1.width > rect2.x && rect1.x < rect2.x + rect2.width;
// 判断y轴投影是否重叠
const yOverlap = rect1.y + rect1.height > rect2.y && rect1.y < rect2.y + rect2.height;
// 两个轴都重叠则发生碰撞
return xOverlap && yOverlap;
}
// 使用示例
const rectA = { x: 10, y: 10, width: 50, height: 50 };
const rectB = { x: 30, y: 30, width: 50, height: 50 };
console.log(checkRectCollision(rectA, rectB)); // 输出true,两个矩形有重叠
圆形碰撞检测算法
圆形碰撞适用于圆形角色、圆形按钮等场景,核心原理是计算两个圆心之间的距离,若距离小于两个圆的半径之和,则说明两个圆发生了碰撞。
假设两个圆的属性分别为:圆A的圆心坐标(x1,y1),半径r1;圆B的圆心坐标(x2,y2),半径r2。首先计算两个圆心之间的距离d,公式为d = Math.sqrt((x2-x1)^2 + (y2-y1)^2),若d < r1 + r2则发生碰撞。
为了优化性能,避免开方运算,也可以比较距离的平方和半径和的平方,即(x2-x1)^2 + (y2-y1)^2 < (r1 + r2)^2,结果一致但运算速度更快。
对应的JavaScript实现代码如下:
/**
* 圆形碰撞检测函数
* @param {Object} circle1 圆1 {x, y, radius}
* @param {Object} circle2 圆2 {x, y, radius}
* @returns {boolean} 是否发生碰撞
*/
function checkCircleCollision(circle1, circle2) {
// 计算圆心x轴差值
const dx = circle1.x - circle2.x;
// 计算圆心y轴差值
const dy = circle1.y - circle2.y;
// 计算距离的平方
const distanceSquare = dx * dx + dy * dy;
// 计算半径和的平方
const radiusSum = circle1.radius + circle2.radius;
const radiusSumSquare = radiusSum * radiusSum;
// 距离平方小于半径和平方则发生碰撞
return distanceSquare < radiusSumSquare;
}
// 使用示例
const circleA = { x: 100, y: 100, radius: 20 };
const circleB = { x: 115, y: 115, radius: 20 };
console.log(checkCircleCollision(circleA, circleB)); // 输出true,两个圆有重叠
圆形与矩形碰撞检测算法
圆形和矩形的碰撞检测相对复杂,核心思路是找到矩形上距离圆心最近的点,再计算该点与圆心的距离是否小于圆的半径。
具体实现步骤为:
- 先判断圆心是否在矩形内部,如果是则直接判定为碰撞
- 如果圆心不在矩形内部,找到矩形上距离圆心最近的点的坐标
- 计算该最近点与圆心的距离,若距离小于圆的半径则发生碰撞
对应的JavaScript实现代码如下:
/**
* 圆形与矩形碰撞检测函数
* @param {Object} circle 圆 {x, y, radius}
* @param {Object} rect 矩形 {x, y, width, height}
* @returns {boolean} 是否发生碰撞
*/
function checkCircleRectCollision(circle, rect) {
// 矩形边界
const rectLeft = rect.x;
const rectRight = rect.x + rect.width;
const rectTop = rect.y;
const rectBottom = rect.y + rect.height;
// 先判断圆心是否在矩形内部
const isCircleInRect = circle.x >= rectLeft && circle.x <= rectRight &&
circle.y >= rectTop && circle.y <= rectBottom;
if (isCircleInRect) {
return true;
}
// 找到矩形上距离圆心最近的点
let closestX = circle.x;
let closestY = circle.y;
if (circle.x < rectLeft) {
closestX = rectLeft;
} else if (circle.x > rectRight) {
closestX = rectRight;
}
if (circle.y < rectTop) {
closestY = rectTop;
} else if (circle.y > rectBottom) {
closestY = rectBottom;
}
// 计算最近点与圆心的距离平方
const dx = circle.x - closestX;
const dy = circle.y - closestY;
const distanceSquare = dx * dx + dy * dy;
// 比较距离平方和半径平方
return distanceSquare < circle.radius * circle.radius;
}
// 使用示例
const testCircle = { x: 60, y: 60, radius: 15 };
const testRect = { x: 10, y: 10, width: 50, height: 50 };
console.log(checkCircleRectCollision(testCircle, testRect)); // 输出true,圆与矩形碰撞
算法选择建议
不同的碰撞检测算法适配不同的场景,开发者可以根据实际需求选择:
| 算法类型 | 适用场景 | 性能特点 |
|---|---|---|
| 矩形碰撞 | DOM元素碰撞、矩形角色游戏 | 计算简单,性能最优 |
| 圆形碰撞 | 圆形角色、圆形交互区域 | 计算量适中,无开方运算时性能较好 |
| 圆形矩形碰撞 | 混合形状物体检测 | 计算逻辑稍复杂,性能略低于前两种 |
在实际开发中,如果检测的物体数量较多,还可以结合空间划分算法(如四叉树)优化检测性能,减少不必要的碰撞检测计算,提升整体运行效率。
JavaScript碰撞检测矩形碰撞圆形碰撞算法实现修改时间:2026-07-08 13:48:42