一文搞定多边形碰撞检测:p5.collide2D collidePolyPoly完整教程
【免费下载链接】p5.collide2DA collision detection library for 2D geometry in p5.js项目地址: https://gitcode.com/gh_mirrors/p5/p5.collide2D
p5.collide2D 是 p5.js 社区的 2D 碰撞检测库,其中的 collidePolyPoly 函数用来判断两个任意多边形是否在 2D 空间中发生碰撞。本教程带你从安装到原理,用 3 行核心代码实现游戏碰撞、按钮点击检测等常见效果。
为什么选择 p5.collide2D 做多边形碰撞检测?
p5.js 是一款深受开发者和设计师喜爱的 JavaScript 创意编程库。当你的作品需要"碰撞"效果——比如角色碰到障碍物、鼠标点中了某个形状——就需要碰撞检测。
p5.collide2D正是为此而生的扩展库:
- 🎮覆盖全面:包含点、圆、矩形、线段、多边形、三角形等 2D 几何碰撞检测
- ⚡接口极简:所有函数只返回
true(碰撞)或false(未碰撞) - ✨任意边数:多边形系列函数支持任意边数,甚至能处理自相交的"折叠"多边形
- 📦零依赖:单个 JS 文件即可引入,无需任何构建步骤
其中collidePolyPoly是"多边形对多边形"碰撞的核心函数,学会它还能顺带搞定三角形对三角形等组合场景。
p5.collide2D 三步安装指南
第一步:准备 p5.js 核心
p5.collide2D 依赖 p5.js 核心库,必须先加载 p5.js。
第二步:引入扩展文件
项目根目录提供了压缩版文件p5.collide2d.min.js,在index.html中按顺序引用即可:
<!-- 先加载 p5.js 核心,再加载 p5.collide2D --> <script defer src="p5.min.js"></script> <script defer src="p5.collide2d.min.js"></script>如需远程引用,可改用 p5.collide2d 的 CDN 地址,加载顺序保持不变。
第三步:验证是否成功
在浏览器控制台输入typeof collidePolyPoly,输出"function"即代表安装完成。
collidePolyPoly 工作原理详解
函数签名非常简洁:
collidePolyPoly(polygon1, polygon2, [interiorCollision])| 参数 | 说明 |
|---|---|
| polygon1 | 多边形 1 的顶点数组,每个元素是 p5.Vector |
| polygon2 | 多边形 2 的顶点数组 |
| interiorCollision | 可选,默认 false,控制是否检测"一个完全包含在另一个内部" |
内部算法可以概括为 4 步:
- 拆成边:依次取出多边形 1 的当前顶点与下一个顶点,组成一条边
- 逐边检测:检查这条边是否和多边形 2 的任意一条边相交
- 提前结束:只要有一条边命中,立即返回
true,不再检测剩余部分(所以速度很快) - 内含检测:当
interiorCollision为true时,额外检查一个多边形是否完全位于另一个内部
实现细节可以查看源码 p5.collide2d.js(第 418–449 行)。向量版collidePolyPolyVector(第 451–453 行)与它行为完全一致,按喜好选用即可。
快速上手:最小可用示例
下面示例中有一个静止的正八边形和跟随鼠标的小三角形,碰撞时描边变为红色:
let polyA = []; // 静止的八边形 let triB = []; // 跟随鼠标的三角形 let hit = false; function setup() { createCanvas(500, 400); // 生成八边形顶点(以画布中心为圆心、半径 100) for (let i = 0; i < 8; i++) { let a = (TAU / 8) * i; polyA.push(createVector(250 + cos(a) * 100, 200 + sin(a) * 100)); } } function draw() { background(255); // 跟随鼠标生成三角形顶点 triB = [ createVector(mouseX, mouseY), createVector(mouseX + 40, mouseY), createVector(mouseX + 20, mouseY + 40) ]; drawPoly(polyA); drawPoly(triB); hit = collidePolyPoly(polyA, triB); // 关键的一行! stroke(hit ? color('red') : 0); print('colliding?', hit); } function drawPoly(p) { beginShape(); for (let v of p) vertex(v.x, v.y); endShape(CLOSE); }核心就是hit = collidePolyPoly(polyA, triB)一行,拿到hit后就能改颜色、播放音效或触发其他逻辑。
理解 interiorCollision 参数,避免漏判碰撞
新手最容易踩的坑:当一个多边形完全在另一个内部时,默认会判定为"未碰撞"。
原因是默认算法只检查"边与边是否相交"——小多边形整体嵌在大多边形里时,彼此的边根本碰不到。
解决方法是把第三个参数传true:
hit = collidePolyPoly(polyA, triB, true);开启后,函数会额外检查"某个多边形的顶点是否落在另一个内部"。代价是计算量增加,所以默认关闭以节省性能。大多数游戏场景用默认值就够了,需要处理"包含关系"时再开启。
多边形碰撞检测的 5 个实用场景
- 按钮点击检测—— 把形状画成按钮,在
mousePressed时判断鼠标所在多边形,触发回调 - 随机放置不重叠—— 随机生成多边形位置时,若
collidePolyPoly返回true就重新放置,保证物体互不重叠 - 游戏碰撞判定—— 经典场景:玩家(多边形)与障碍物(多边形)的实时碰撞检测
- 三角形碰撞—— 把三角形定义为 3 个向量的数组,传给
collidePolyPoly即可实现三角形对三角形 - 调试可视化—— 在
setup()里调用collideDebug(true),碰撞发生时会在画面上标出碰撞点,排查问题一目了然
常见问题 FAQ
Q:为什么检测不到碰撞?
排查三点:① 顶点数组的每个元素必须是p5.Vector,不能只是两个数字;② 是否一个多边形完全在另一个内部(需开启interiorCollision);③ 开启collideDebug(true)把碰撞点可视化出来观察。
Q:性能怎么样?
很快。算法在第一条边命中时就会提前返回。如果多边形边数很多,建议保持interiorCollision关闭以节省计算。
Q:坐标系模式有要求吗?
p5.collide2D 默认假设rectMode(CORNER)与ellipseMode(CENTER),与画布默认状态一致,一般无需额外设置。
Q:其他形状组合该用哪个函数?
库提供了完整的 2D 碰撞检测函数家族,可按形状组合选择:
| 函数 | 用途 |
|---|---|
| collidePointPoint | 点对点 |
| collideCircleCircle | 圆对圆 |
| collideRectRect | 矩形对矩形 |
| collideRectCircle | 矩形对圆 |
| collideLineLine | 线段对线段 |
| collidePointPoly | 点对多边形 |
| collideCirclePoly | 圆对多边形 |
| collideRectPoly | 矩形对多边形 |
| collideLinePoly | 线段对多边形 |
| collidePolyPoly | 多边形对多边形(本文主角) |
总结
到这里,p5.js 多边形碰撞检测的关键点就全部掌握了:
- 两段 script 标签即可完成 p5.collide2D 安装
collidePolyPoly(polyA, polyB)一行判断两个多边形是否碰撞,返回布尔值interiorCollision是避坑关键,用于检测"完全包含"的情况
从此你的创意作品里,游戏碰撞、点击判定、随机布局都能轻松实现——p5.collide2D 的collidePolyPoly会是你做多边形碰撞检测的得力助手。
【免费下载链接】p5.collide2DA collision detection library for 2D geometry in p5.js项目地址: https://gitcode.com/gh_mirrors/p5/p5.collide2D
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考