import { _decorator, Component, Vec2, SystemEventType, EventTouch, UITransform, EventHandler, Vec3, v3 } from 'cc'; const { ccclass, property } = _decorator; /** * @description 触摸辅助器,支持多边形区域点击检测,并且添加ceator不带有的tap事件 * @author Soonsky */ @ccclass('TouchHelper') export class TouchHelper extends Component { @property({ tooltip: "是否可以点击" }) canTouch: boolean = true; @property({ tooltip: "在多边形范围内产生点击", type: EventHandler }) onInPolygon: EventHandler; @property({ tooltip: "在多边形范围外产生点击", type: EventHandler }) onOutPolygon: EventHandler; @property({ tooltip: "在节点范围内产生点击", type: EventHandler }) onTouchTap: EventHandler; @property({ tooltip: "是否与需要多边形检查" }) needPolygon: boolean = false; @property({ type: [Vec2], tooltip: "多边形定点位置信息(局部坐标,至少3个点)" }) points: Array = []; @property({ tooltip: "点击在多边形区域内时是否阻止事件冒泡" }) stopPropagation = false; private isMoved = false; start() { this.node.on(SystemEventType.TOUCH_END, this.onTouchEnd, this); this.node.on(SystemEventType.TOUCH_CANCEL, this.onTouchCancel, this); this.node.on(SystemEventType.TOUCH_MOVE, this.onTouchMove, this); } private onTouchEnd(e: EventTouch): void { if (this.canTouch && this.needPolygon && this.points.length >= 3) { let touchPoint = e.getUILocation(); let localPoint = this.node.getComponent(UITransform).convertToNodeSpaceAR(v3(touchPoint.x, touchPoint.y, 0)); let result = this.pointInPoly(localPoint, this.points); if (!this.isMoved) { if (result) { if (this.stopPropagation) { e.propagationStopped = true; } this.canTouch && this.onInPolygon && this.onInPolygon.emit([]); } else { this.canTouch && this.onOutPolygon && this.onOutPolygon.emit([]); } } } if (this.canTouch) { if (!this.isMoved) { this.canTouch && this.onTouchTap && this.onTouchTap.emit([]); } } this.isMoved = false; } private onTouchMove(e: EventTouch) { if (e.getAllTouches().length > 1) { this.isMoved = true; return } this.isMoved = Vec2.distance(e.getStartLocation(), e.getLocation()) > 20; } private onTouchCancel(e: EventTouch) { this.isMoved = false; } private pointInPoly(point: Vec2 | Vec3, polyPoints: Vec2[]) { for (var c = false, i = -1, l = polyPoints.length, j = l - 1; ++i < l; j = i) ((polyPoints[i].y <= point.y && point.y < polyPoints[j].y) || (polyPoints[j].y <= point.y && point.y < polyPoints[i].y)) && (point.x < (polyPoints[j].x - polyPoints[i].x) * (point.y - polyPoints[i].y) / (polyPoints[j].y - polyPoints[i].y) + polyPoints[i].x) && (c = !c); return c; } }