cocos creator 2.4.4
因为需要这样一个功能,不知道图片的形状,但是要实现图片和其他物体碰撞
所以开始觉得没问题,因为cocos creator的PolygonCollider中在编辑器Regenerate Point可以实现生成图片的多边形碰撞点,
后来看到代码中获取不到Regenerate Point的方法,看了编辑器的底层代码,是只有在编辑器中才能使用
所以只能自己实现获取图片的轮廓点,把得到的点赋值给多边形的points数组就可以了
1,主要使用的代码就是生成图片的轮廓点 来自于 github https://github.com/sakri/MarchingSquaresJS
两个图片 绑定的碰撞器 分别是多边形 和矩形碰撞器
下面看一下我实现的,白线是生成的碰撞点,蓝框是bindingBox, 人头图形只有接触到白线的时候 才会触发碰撞
在蓝框内,没接触到白线是没有碰撞的 全部代码
const { ccclass, property } = cc._decorator;
// 动态生成多边形碰撞点
// require("./MarchingSquares"); // 可以不引用,是直接绑定到window的
@ccclass
export default class DynamicColliderPoints extends cc.Component {
@property(cc.Sprite)
sp: cc.Sprite = null; // 多边形碰撞 图
// LIFE-CYCLE CALLBACKS:
onLoad() {
// 开启物理系统
var mngr = cc.director.getCollisionManager();
mngr.enabled = true;
mngr.enabledDebugDraw = true;
mngr.enabledDrawBoundingBox = true;
cc.director.getPhysicsManager().enabled = true;
let _this = this;
// 获取Texture2d
let t = this.sp.spriteFrame.getTexture();
// 创建h5 image标签
var imgNode = document.createElement('img');
imgNode.src = t.nativeUrl; // 把图片的本地地址加载进去
imgNode.onload = function () {// 等待图片加载完成
// 创建canvas用于渲染画布 获取轮廓点
var canvas = document.createElement('canvas');
var ctx = canvas.getContext('2d');
var w = imgNode.width;
var h = imgNode.height;
// 图片的宽高给canvas
canvas.width = w;
canvas.height = h;
var x = canvas.width / 2; //画布宽度的一半
var y = canvas.height / 2;//画布高度的一半
ctx.clearRect(0, 0, canvas.width, canvas.height);//先清掉画布上的内容
ctx.translate(x, y);//将绘图原点移到画布中点
ctx.rotate(Math.PI);//旋转角度
ctx.scale(-1.06, 1.06);// 放大一点,方便看清楚轮廓 有canvas 画出来的是镜像 所以这里x方向反过来
ctx.translate(-x, -y);//将画布原点移动
ctx.drawImage(imgNode, 0, 0, w, h); // 画布总宽高和图片是一样的 所以从0,0开始绘制,才能完全把图片画出来
// 重点是这里 方法 获取图片轮廓上的点
var pathPoints = window.MarchingSquares.getBlobOutlinePoints(canvas);
var points: cc.Vec2[] = [];
for (var i = 0; i < pathPoints.length; i += 2) {
points.push(cc.v2(pathPoints[i] - x, pathPoints[i + 1] - y)) // 生成 x ,y 这里减去宽高的一半,是因为canvas画图的锚点是在0,0,和cocos creator不一样
}
// 处理点 我这里生成的是400多,只留下最后50多个点就可以了
let newPoints = _this.disposArray(points,Math.floor(Math.log2(points.length/50)));
// points 给多边形碰撞器 这里生成的点比较多,影响性能 自己可以酌情删减
let poy = _this.sp.node.getComponent(cc.PolygonCollider);
poy.points = newPoints;
console.log(newPoints);
}
}
// 处理数组 count是执行次数 每次删除数组的一半
disposArray(points,count)
{
let arr = [];
for(var i=0;i<points.length;i++){
if(i%2==0){
arr.push(points[i]);
}
}
count--;
if(count<=0||arr.length<60)
{
return arr;
}
else
{
return this.disposArray(arr,count);
}
}
start() {
// 测试碰撞
setTimeout(() => {
this.node.position = cc.v3(92, -114)
}, 2000);
setTimeout(() => {
this.node.position = cc.v3(92, -99)
}, 5000);
setTimeout(() => {
this.node.position = cc.v3(92, -159)
}, 7000);
}
// 检测碰撞,碰到障碍物不移动
onCollisionEnter(other, self) {
console.log('on collision enter', other);
}
onCollisionStay(other, self) {
console.log('on collision stay', other);
}
onCollisionExit(other, self) {
// console.log('on collision exit');
}
// update (dt) {}
}
这里主要的代码是 来自https://github.com/sakri/MarchingSquaresJS里的MarchingSquares.js 直接放在项目下面就可以,不需要引用,因为是直接绑定到window,如果拿不到,那就 require("./MarchingSquares")引用一下
参考链接:
https://www.cnblogs.com/flyfox1982/p/14601659.html
物理引擎中链条形状根据对应贴图轮廓获取顶点是怎么实现的呢 - Creator 2.x - Cocos中文社区
h5 canvas透明度图像边缘提取算法_canvas提取图片前景-CSDN博客
大牛也可以看看 From PNG to Box2D – first attempt | Emanuele Feronato