Canvas无内置碰撞检测,需手动实现:矩形用AABB法判断xy轴投影重叠,圆形通过圆心距平方与半径和平方比较。

Canvas 本身不提供内置的碰撞检测功能,需要开发者手动计算图形之间的几何关系。核心思路是:把绘制在 Canvas 上的物体抽象为可计算的数学形状(如矩形、圆形、多边形),再通过对应的数学公式判断它们是否重叠。
矩形与矩形碰撞(AABB)
这是最常用、性能最好的方式,适用于大多数轴对齐的物体(比如方块、按钮、角色贴图框)。原理是判断两个矩形在 x 和 y 轴上的投影是否有重叠。
假设两个矩形由 {x, y, width, height} 描述:
- 水平方向不相交:rect1.x + rect1.width ≤ rect2.x 或 rect2.x + rect2.width ≤ rect1.x
- 垂直方向不相交:rect1.y + rect1.height ≤ rect2.y 或 rect2.y + rect2.height ≤ rect1.y
- 只要两个方向都相交,就发生碰撞 —— 即取反后判断:
!(水平不相交 || 垂直不相交)→rect1.x rect2.x && rect1.y rect2.y
圆形与圆形碰撞
适合球体、头像、粒子等圆形对象。只需比较两圆心距离是否小于半径之和。
给定两个圆 {x, y, radius}:
- 先算 x、y 方向差值:
dx = circle1.x - circle2.x,dy = circle1.y - circle2.y - 再算距离平方(避免开方提升性能):
distanceSq = dx * dx + dy * dy - 碰撞条件:
distanceSq
矩形与圆形碰撞
常见于角色(圆形判定圈)与墙壁(矩形)交互。关键是找出矩形上离圆心最近的点,再测该点到圆心的距离。
- 求矩形内/边上离圆心最近的坐标:
closestX = Math.max(rect.x, Math.min(circle.x, rect.x + rect.width))closestY = Math.max(rect.y, Math.min(circle.y, rect.y + rect.height)) - 计算该点到圆心距离平方:
dx = circle.x - closestX,dy = circle.y - closestY,distanceSq = dx*dx + dy*dy - 若
distanceSq ,则碰撞
进阶:像素级或路径级检测
当图形旋转、缩放或形状不规则时,AABB 和圆形检测会不够精确。可考虑:
- 分离轴定理(SAT):适用于凸多边形,精度高但实现复杂
-
位图掩码法:将两个物体渲染到离屏 canvas,用
getImageData()提取像素,逐点比对非透明像素是否重叠(适合小范围、低频检测) - 简化为多个基础形状组合:例如把一个斜着的飞船拆成 1 个矩形主体 + 2 个圆形引擎,分别检测
实际开发中,建议先用 AABB 做粗筛(Broad Phase),再对可能碰撞的对象用更精确的方式细筛(Narrow Phase),兼顾性能与准确性。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











