Cocos Creator不规则触摸点击实现

不规则的触摸之前写过一篇Blog,利用Mask组件实现的->
Cocos-Mask触摸穿透Alpha

当时犯了个想当然的错误:圆形,矩形Mask都可以实现Mask以外的位置不触发点击事件,而IMAGE_STENCIL类型可以实现不规则的Mask。

今天实际使用了下,发现并不是这样的,使用方式如下:

  1. 父节点添加on事件,添加Mask组件,使用IMAGE_STENCIL创建不规则组件。
  2. 添加一个有Sprite的子节点,Sprite按Mask不规则正常显示。
  3. on事件TOUCH_START,在Mask以外的位置同样触发。

发项情况不对,查了下源码
CCMask源码

Mask重写_hitTest

唉,真悲剧,CCMask重写了_hitTest,IMAGE_STENCIL跟RECT的处理方式是一样的。这条路走不通了,只能另辟蹊径。

思路还是重写_hitTest

cc.Intersection封装了很多Collider点、线、面碰撞的检测函数,
可以利用PolygonCollider组件实现一个不规则碰撞的方法。

  1. Node节点需要添加cc.PolygonCollider,否则按原函数处理
  2. 获取cc.PolygonCollider组件,检测碰撞。触摸点坐标需要转NodeSpace,并且Anchor为(0.5,0.5)即:节点中心为原点。

源码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
cc.Class({
extends: cc.Component,
editor: CC_EDITOR && {
menu: 'i18n:Component/PolygonHitTest',
},
properties: {
},
/**
* 加载
*/
onLoad() {
this.node._oldHitTest = this.node._hitTest.bind(this.node);
this.node._hitTest = this.polygonHitTest.bind(this.node);
},
/**
* 不规则多边形触摸测试
* @param {触摸点} point
* @param {监听} listener
*/
polygonHitTest(point, listener) {
var polygonCollider = this.getComponent(cc.PolygonCollider);
if (polygonCollider) {
point = this.convertToNodeSpace(point);
point.x -= this.getContentSize().width / 2;
point.y -= this.getContentSize().height / 2;
return cc.Intersection.pointInPolygon(point, polygonCollider.points);
} else {
return this._oldHitTest(point, listener);
}
}
});

实现完成,弥补错误。