关于不规则按钮的点击透明判定

因为项目需要,需要精确点击图片,但是发现图片的判定区域实际上是方形,当时上网查找解决办法,
看到有readPixels,然后我去试了之后一直提示renderbuffur缓冲未完成巴拉巴拉的,就是获取不到它的像素信息。还有用多边形碰撞的,但是不适用于我这种几十个图片检测的,为此非常苦恼,就C#做了个工具,用C#读取图片的像素信息保存下来,然后再在js里解开判断,当时就这样先处理着,就是有点费事。
后来项目需要做个截屏,我在分析截屏代码的时候突然有了启发。我看有很多同学也有和我一样的困扰所以和大家分享一下思路。
screenShot screenShot2
这不就能拿到像素信息了么!需要相机照一下!
结合之前大佬的修改testHit的方法。我额外加了个备用的相机,只在拍的时候开启,其余隐藏。以下就是代码

cc.dynamicAtlasManager.enabled = true;
cc.macro.CLEANUP_IMAGE_CACHE = false;
cc.Class({
    extends: cc.Component,

properties: {
    nodeTestHit: false,
},

onLoad() {
    this.initEvent();
},

initEvent() {
    if (!this.nodeTestHit) this.node._hitTest = this.hitTest.bind(this);
    this.node.on(cc.Node.EventType.TOUCH_START, () => { }, this);
    this.node.on(cc.Node.EventType.TOUCH_END, () => { }, this);
    this.node.on(cc.Node.EventType.TOUCH_CANCEL, () => { }, this);
},

hitTest(location) {
    let spriteFrame = this.node.getComponent(cc.Sprite).spriteFrame;
    if (spriteFrame == null) {
        return false;
    }
    let node = this.node;
    //坐标转换
    let posInNode = this.node.convertToNodeSpaceAR(location);
    var size = node.getContentSize();
    let rect = spriteFrame.getRect();
    let offset = spriteFrame.getOffset();
    //如果点击位置超出图片范围,则无效
    if (Math.abs(posInNode.x) > size.width / 2 || Math.abs(posInNode.y) > size.height / 2) {
        return false;
    }
    else {
        if (!this.camera)
            this.camera = this.node.parent.getChildByName("check_camera").getComponent(cc.Camera);
        if (!this.camera) return;
        this.camera.node.active = true;
        let posInRect = cc.v2(parseInt(posInNode.x - offset.x + rect.width / 2), parseInt(posInNode.y - offset.y + rect.height / 2));
        let tex = spriteFrame.getTexture();
        let data;
        this.camera.enable = true;
        let destory = false;
        if (tex instanceof cc.RenderTexture) {
            this.node.group = "UI";
            rt = tex;
        }
        else {
            this.node.group = "camera";
            var rt = new cc.RenderTexture()
            if (tex.width == 2048) console.log("@@@@@@@@@@@@@@@@@@@@@@@" + this.node.name);
            rt.initWithSize(tex.width, tex.height, cc.gfx.RB_FMT_S8);
            rt.drawTextureAt(tex, 0, 0);
            destory = true;
        }
        // data就是这个texture的rgba值数组
        this.camera.targetTexture = rt;
        this.camera.render(undefined);
        //图集里的图片可能会旋转
        if (spriteFrame.isRotated()) {
            data = rt.readPixels(null, rect.x + posInRect.y, rect.y + posInRect.x, 1, 1);
        }
        else {
            data = rt.readPixels(null, rect.x + posInRect.x, rect.y + rect.height - posInRect.y, 1, 1);
        }
        this.camera.targetTexture = null;
        this.camera.enable = false;
        this.camera.node.active = false;
        this.node.group = "UI";
        destory && rt.destroy();
        if (data[3] <= 200) {
            return false
        }
        else {
            return true
        }
    }
},
onDestroy: function () {
    if (!this.nodeTestHit) this.node._hitTest = this.hitTest.bind(null);
},
});


脚本挂上去
image
检测相机的设置

最后附上demotestAph.rar (695.9 KB)
欢迎各位大佬指教

2赞

顶下自己 :face_with_monocle:

1赞

乐于分享 :+1:

棒!顶一下