# 2D 碰撞检测

2D 游戏中的碰撞检测算法依赖于可碰撞物体的形状（例如：矩形与矩形、矩形与圆形、圆形与圆形）。通常情况下，你使用的简单通用形状，会被称为“碰撞盒（hitbox）”的实体所覆盖，尽管发生的碰撞并不是像素那样完美契合，但它看起来也足够好，而且可跨多个实体执行碰撞。本文提供了一系列较为通用的 2D 游戏中碰撞检测技术。

## 轴对齐包围盒

js
``````Crafty.init(200, 200);

const dim1 = { x: 5, y: 5, w: 50, h: 50 };
const dim2 = { x: 20, y: 10, w: 60, h: 40 };

const rect1 = Crafty.e("2D, Canvas, Color").attr(dim1).color("red");

const rect2 = Crafty.e("2D, Canvas, Color, Keyboard, Fourway")
.fourway(2)
.attr(dim2)
.color("blue");

rect2.bind("EnterFrame", function () {
if (
rect1.x < rect2.x + rect2.w &&
rect1.x + rect1.w > rect2.x &&
rect1.y < rect2.y + rect2.h &&
rect1.y + rect1.h > rect2.y
) {
// 检测到碰撞发生！
this.color("green");
} else {
// 没有碰撞
this.color("blue");
}
});
``````

## 圆形碰撞

js
``````Crafty.init(200, 200);

const dim1 = { x: 5, y: 5 };
const dim2 = { x: 20, y: 20 };

Crafty.c("Circle", {
this.w = this.h = radius * 2;
this.color = color || "#000000";

this.bind("Move", Crafty.DrawManager.drawAll);
return this;
},

draw() {
const ctx = Crafty.canvas.context;
ctx.save();
ctx.fillStyle = this.color;
ctx.beginPath();
ctx.arc(
0,
Math.PI * 2,
);
ctx.closePath();
ctx.fill();
ctx.restore();
},
});

const circle1 = Crafty.e("2D, Canvas, Circle").attr(dim1).circle(15, "red");

const circle2 = Crafty.e("2D, Canvas, Circle, Fourway")
.fourway(2)
.attr(dim2)
.circle(20, "blue");

circle2.bind("EnterFrame", function () {
const dx = circle1.x - circle2.x;
const dy = circle1.y - circle2.y;
const distance = Math.sqrt(dx * dx + dy * dy);

const colliding = distance < circle1.radius + circle2.radius;
this.color = colliding ? "green" : "blue";
});
``````