[TOC]
前言
最近有初学CocosCreator的小伙伴问到一个点击穿透的问题,正好整理些方案一起来看下。通常在制作课件的过程中,会遇到点击或拖拽多边图形的需求,很多时候就会不可避免的遇到一个问题:两个图形的叠加在了一起。比如A和B两个Sprite,我们会发现,层级高的会被点击,但想点击下方的B,却始终或者无法精准的点到B,这跟cocos本身的点击机制有关。
有什么办法可以解决这个问题吗? 答案肯定是有的,接下来就一起看下几种解决方案。
一、知识准备
通过修改节点的_hitTest函数即可快速的达到我们想要的效果,对于刚接触cocos的开发者来说,可能对这个不是很熟悉,因为官方原本也没有直接暴露这个方法给外部使用,算是私有方法。为了让大家更清晰的了解我们接下来要说的内容,还是先把_hitTest函数做一下讲解,在CCNode.js文件中我们可以找到相关代码段(官方源码是没有注释的):// 使用_hitTest的地方(省略了部分代码段)
var _touchStartHandler = function (touch, event) {
...
if (node._hitTest(pos, this)) {
...
return true;
}
return false;
};
...
/**
* @param point 触发的坐标点位置
* @param listener 节点本身
*/
_hitTest (point, listener) {
let w = this._contentSize.width,
h = this._contentSize.height,
cameraPt = _vec2a,
testPt = _vec2b;
// 获取节点所在的第一个摄像机
let camera = cc.Camera.findCamera(this);
if (camera) {
// 将一个摄像机坐标系下的点转换到世界坐标系下
camera.getCameraToWorldPoint(point, cameraPt);
}
else {
cameraPt.set(point);
}
// 更新世界坐标矩阵
this._updateWorldMatrix();
// 逆矩阵赋值计算, 返回的是下面要用到的_mat4_temp
math.mat4.invert(_mat4_temp, this._worldMatrix);
// 变换矩阵赋值计算,返回的是计算后的testPt
math.vec2.transformMat4(testPt, cameraPt, _mat4_temp);
// 根据锚点和宽高计算出需要检测的点的xy值
testPt.x += this._anchorPoint.x * w;</