追梦何须问成败,只管向前。
多边形点击工具,挂载到编辑器使用
支持2.x,简单修改后3.x也能用。
脚本:TouchHelper.ts
// import { _decorator, Component, Vec2, SystemEventType, EventTouch, UITransform, EventHandler, Vec3, v3 } from 'cc';// 3.x版本写法
const { ccclass, property } = cc._decorator;
/**
* @description 触摸辅助器,支持多边形区域点击检测
* 需要给节点添加组件
* bug:拿不到target
* @author Soonsky编写的3.x版本, xhx修改到2.x版本
*/
@ccclass//('TouchHelper')
export class TouchHelper extends cc.Component {
@property({ tooltip: "是否可以点击" }) canTouch: boolean = true;
@property({ tooltip: "在多边形范围内产生点击", type: cc.Component.EventHandler }) onInPolygon: cc.Component.EventHandler = new cc.Component.EventHandler();
@property({ tooltip: "在多边形范围外产生点击", type: cc.Component.EventHandler }) onOutPolygon: cc.Component.EventHandler = new cc.Component.EventHandler();
@property({ tooltip: "在节点范围内产生点击", type: cc.Component.EventHandler }) onTouchTap: cc.Component.EventHandler = new cc.Component.EventHandler();
@property({ tooltip: "是否与需要多边形检查" }) needPolygon: boolean = false;
@property({ type: [cc.Vec2], tooltip: "多边形定点位置信息(局部坐标,至少3个点)" }) points: Array<cc.Vec2> = [];
// @property({ tooltip: "点击在多边形区域内时是否阻止事件冒泡" }) stopPropagation = false;// 2.x无效且报错
private isMoved = false;
private comp_btn: cc.Button = null;
start() {
this.comp_btn = this.node.getComponent(cc.Button) || this.node.addComponent(cc.Button);
this.node.on(cc.Node.EventType.TOUCH_END, this.onTouchEnd, this);
this.node.on(cc.Node.EventType.TOUCH_CANCEL, this.onTouchCancel, this);
this.node.on(cc.Node.EventType.TOUCH_MOVE, this.onTouchMove, this);
}
private onTouchEnd(e: cc.Touch): void {
if (this.canTouch && this.needPolygon && this.points.length >= 3) {
let touchPoint = e.getLocation();
let localPoint = this.node.convertToNodeSpaceAR(new cc.Vec2(touchPoint.x, touchPoint.y));
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([this.comp_btn]);
} else {
this.canTouch && this.onOutPolygon && this.onOutPolygon.emit([this.comp_btn]);
}
}
}
if (this.canTouch) {
if (!this.isMoved) {
this.canTouch && this.onTouchTap && this.onTouchTap.emit([this.comp_btn]);
}
}
this.isMoved = false;
}
private onTouchMove(e: cc.Event.EventTouch) {
if (e.getTouches().length > 1) { this.isMoved = true; return }// getAllTouches
// this.isMoved = cc.Vec2.distance(e.getStartLocation(), e.getLocation()) > 20;// 2.4.x写法
this.isMoved = e.getStartLocation().sub(e.getLocation()).mag() > 20;// 2.2.x及以下写法
}
private onTouchCancel(e: cc.Event.EventTouch) {
this.isMoved = false;
}
private pointInPoly(point: cc.Vec2 | cc.Vec3, polyPoints: cc.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;
}
}
挂载组件:
点击有效范围:
整理不易,关注收藏不迷路。
目录:CocosCreator经典笔记_神兽白泽-CSDN博客
笔者qq、微信:1302109196
qq群:415468592