cocos creator 根据图片形状 实现代码动态创建多边形碰撞器的点PolygonCollider,因为cocos的多边形Regenerate Points功能只能在编辑器使用

本文介绍了如何在Cocos Creator 2.4.4中,利用MarchingSquaresJS库动态生成图片轮廓碰撞点,以实现图片与其他物体的碰撞检测。由于Cocos Creator的PolygonCollider在编辑器外无法使用Regenerate Points功能,作者通过引入MarchingSquares.js代码,实现了在运行时自动生成碰撞点并赋值给PolygonCollider的points数组。
摘要由CSDN通过智能技术生成

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

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值