| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364 |
- 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<Vec2> = [];
- @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;
- }
- }
|