js实现碰撞
JavaScript 实现碰撞检测
矩形碰撞检测
矩形碰撞是最基础的检测方法,通过比较两个矩形的位置和尺寸判断是否重叠。
function checkRectCollision(rect1, rect2) {
return (
rect1.x < rect2.x + rect2.width &&
rect1.x + rect1.width > rect2.x &&
rect1.y < rect2.y + rect2.height &&
rect1.y + rect1.height > rect2.y
);
}
圆形碰撞检测
圆形碰撞通过计算圆心距离与半径之和的关系实现。
function checkCircleCollision(circle1, circle2) {
const dx = circle1.x - circle2.x;
const dy = circle1.y - circle2.y;
const distance = Math.sqrt(dx * dx + dy * dy);
return distance < circle1.radius + circle2.radius;
}
像素级碰撞检测
对于不规则形状,可通过 canvas 的 getImageData 检测像素透明度。
function checkPixelCollision(obj1, obj2) {
const ctx = document.createElement('canvas').getContext('2d');
ctx.drawImage(obj1.image, 0, 0);
const data1 = ctx.getImageData(0, 0, obj1.width, obj1.height).data;
ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);
ctx.drawImage(obj2.image, 0, 0);
const data2 = ctx.getImageData(0, 0, obj2.width, obj2.height).data;
for (let i = 0; i < data1.length; i += 4) {
if (data1[i + 3] > 0 && data2[i + 3] > 0) {
return true;
}
}
return false;
}
分离轴定理(SAT)
适用于凸多边形的高级碰撞检测算法。
function checkSATCollision(poly1, poly2) {
const axes = [...getAxes(poly1), ...getAxes(poly2)];
for (const axis of axes) {
const proj1 = projectPolygon(poly1, axis);
const proj2 = projectPolygon(poly2, axis);
if (proj1.max < proj2.min || proj2.max < proj1.min) {
return false;
}
}
return true;
}
物理引擎集成
使用现成库如 Matter.js 可简化复杂碰撞检测:
const engine = Matter.Engine.create();
const boxA = Matter.Bodies.rectangle(200, 200, 80, 80);
const boxB = Matter.Bodies.rectangle(210, 210, 80, 80);
Matter.Engine.update(engine);
const collisions = Matter.Query.collides(boxA, [boxB]);
性能优化技巧
- 使用空间分区(如四叉树)减少检测次数
- 先进行粗略的包围盒检测再精细检测
- 对静态物体缓存碰撞检测结果
- 使用 Web Workers 进行离屏计算







