let _textureIdMapDataContainer = {} cc.Class({ extends: cc.Component, properties: { }, // LIFE-CYCLE CALLBACKS: onLoad() { let spriteComp = this.node.getComponent(cc.Sprite) if (spriteComp.type !== cc.Sprite.Type.SIMPLE || spriteComp.sizeMode !== cc.Sprite.SizeMode.RAW) { throw "目前仅支持sprite SizeMode 为RAW, type 为SIMPLE的方式" } this.node._hitTest = this.hitTest.bind(this) }, start() { }, hitTest(location) { cc.log('location',location); let spriteFrame = this.node.getComponent(cc.Sprite).spriteFrame if (spriteFrame == null) { return false } let posInNode = this.node.convertToNodeSpaceAR(location) let rect = spriteFrame.getRect() let offset = spriteFrame.getOffset() //var type = this.node.getComponent("DecorateItemPrefab").m_type // cc.log(type + "--", "xxxxxxxxxxxxxx", type) // cc.log(type + "--", "posInNode", posInNode) // cc.log(type + "--", "rect", rect) // cc.log(type + "--", "offset", offset) if ((posInNode.x < offset.x - rect.width / 2) || (posInNode.y < offset.y - rect.height / 2) || (posInNode.x > (offset.x + rect.width / 2)) || (posInNode.y > (offset.y + rect.height / 2))) { return false } else { let posInRect = cc.v2(parseInt(posInNode.x - offset.x + rect.width / 2), parseInt(posInNode.y - offset.y + rect.height / 2)) // cc.log(type + "--", "posInRect", posInRect) // cc.log(type + "--", "isRotated", spriteFrame.isRotated()) let tex = spriteFrame.getTexture() let data if (tex instanceof cc.RenderTexture) { // 细图(width <= 512 && height <= 512) 被引擎自动打包了 if (cc.sys.platform === cc.sys.QQ_PLAY) { // 玩一玩平台 throw "在玩一玩平台,请确保你的SpriteFrame 的宽高至少有一个大于512, 这样不会被Atlas, 不然被引擎自动Atlas之后,因为玩一玩不支持gl.readPixels 或 getImageData这样的接口,像素就读不出来了" } // data就是这个texture的rgba值数组 if (spriteFrame.isRotated()) { data = rt.readPixels(null, rect.x + posInRect.y, rect.y + posInRect.x, 1, 1) //cc.log(type + "--", "data", data, rect.x + posInRect.y, rect.y + posInRect.x) } else { data = rt.readPixels(null, rect.x + posInRect.x, rect.y + rect.height - posInRect.y, 1, 1) //cc.log(type + "--", "data", data, rect.x + posInRect.x, rect.y + rect.height - posInRect.y) } } else { var dataContainer = _textureIdMapDataContainer[tex.getId()] if (cc.sys.platform === cc.sys.QQ_PLAY) { // 针对玩一玩的特殊方式 if (!dataContainer) { tex.getHtmlElementObj().bkImage || tex.getHtmlElementObj()._generateBKImage() dataContainer = tex.getHtmlElementObj().bkImage _textureIdMapDataContainer[tex.getId()] = dataContainer } var buffer = dataContainer.buffer buffer.rewind() if (spriteFrame.isRotated()) { buffer.jumpBytes(((rect.x + posInRect.y) + (rect.y + posInRect.x) * tex.width) * 4) //cc.log(type + "--", "data", data, rect.x + posInRect.y, rect.y + posInRect.x) } else { buffer.jumpBytes(((rect.x + posInRect.x) + (rect.y + rect.height - posInRect.y) * tex.width) * 4) //cc.log(type + "--", "data", data, rect.x + posInRect.x, rect.y + rect.height - posInRect.y) } data = [buffer.readUint8Buffer(), buffer.readUint8Buffer(), buffer.readUint8Buffer(), buffer.readUint8Buffer()] } else { //Canvas 方式 var scale = 8 var cvs = dataContainer if (!cvs) { cvs = document.createElement("canvas") var ctx = cvs.getContext('2d') cvs.width = tex.width cvs.height = tex.height ctx.drawImage(tex.getHtmlElementObj(), 0, 0, tex.width, tex.height, 0, 0, tex.width / scale, tex.height / scale) _textureIdMapDataContainer[tex.getId()] = cvs } var ctx = cvs.getContext('2d') if (spriteFrame.isRotated()) { data = ctx.getImageData((rect.x + posInRect.y) / scale, (rect.y + posInRect.x) / scale, 1, 1).data //cc.log(type + "--", "data", data, rect.x + posInRect.y, rect.y + posInRect.x) } else { data = ctx.getImageData((rect.x + posInRect.x) / scale, (rect.y + rect.height - posInRect.y) / scale, 1, 1).data //cc.log(type + "--", "data", data, rect.x + posInRect.x, rect.y + rect.height - posInRect.y) } /* //RenderTexture 方式 var rt = dataContainer if (!rt){ rt = new cc.RenderTexture() rt.initWithSize(tex.width, tex.height) rt.drawTextureAt(tex, 0, 0) _textureIdMapDataContainer[tex.getId()] = rt } // data就是这个texture的rgba值数组 if (spriteFrame.isRotated()) { data = rt.readPixels(null, rect.x + posInRect.y, rect.y + posInRect.x, 1, 1) //cc.log(type + "--", "data", data, rect.x + posInRect.y, rect.y + posInRect.x) } else { data = rt.readPixels(null, rect.x + posInRect.x, rect.y + rect.height - posInRect.y, 1, 1) //cc.log(type + "--", "data", data, rect.x + posInRect.x, rect.y + rect.height - posInRect.y) } */ } } if (data[3] <= 0) { cc.log("false"); return false } else { cc.log("true"); return true } } }, onDisable() { cc.log("DecorateHitTest onDisable") let spriteFrame = this.node.getComponent(cc.Sprite).spriteFrame if (spriteFrame == null) { return false } var tex = spriteFrame.getTexture() if (cc.sys.platform === cc.sys.QQ_PLAY) { // 针对玩一玩的特殊方式 var img = _textureIdMapDataContainer[tex.getId()] if (img) { cc.log("DecorateHitTest onDisable QQ bkImage") img.dispose() _textureIdMapDataContainer[tex.getId()] = null } } else { var dataContainer = _textureIdMapDataContainer[tex.getId()] if (dataContainer) { if (dataContainer instanceof cc.RenderTexture) { // RenderTexture 方式 cc.log("DecorateHitTest onDisable renderTexture") dataContainer.destroy() } else { // Canvas 方式 cc.log("DecorateHitTest onDisable canvas") // 暂时不知道如何释放这个引用的Canvas } } _textureIdMapDataContainer[tex.getId()] = null } } // update (dt) {}, });