import { Component, EventTouch, SystemEventType, UITransform, _decorator, Node } from "cc"; import { GeometryUtils } from "../../utils/GeometryUtils"; import { DragSource } from "./DragSource"; import { DragTarget } from "./DragTarget"; const { ccclass, property } = _decorator; /** * 拖拽系统组件 * @description 主场景中丢这个组件即可 * @author 袁浩 */ @ccclass("DragSystem") export class DragSystem extends Component { @property({ tooltip: "可以出发拖拽的节点", type: Node }) public touchNode: Node; private sourceList: DragSource[] = []; private targetList: DragTarget[] = []; private draggingSource: DragSource;//拖拽中的组件 private static thisObject: DragSystem; start() { this.touchNode.on(SystemEventType.TOUCH_MOVE, this.onTouchMove, this); this.touchNode.on(SystemEventType.TOUCH_END, this.onTouchEnd, this); this.touchNode.on(SystemEventType.TOUCH_CANCEL, this.onTouchEnd, this); DragSystem.thisObject = this; } private onTouchMove(event: EventTouch) { if (!this.draggingSource) {//没有进行拖拽 for (let i = 0; i < this.sourceList.length; i++) { if (this.sourceList[i].node.isValid && this.sourceList[i].node.active && this.sourceList[i].getComponent(UITransform).isHit(event.getUILocation())) {//如果跟触摸点碰撞 this.draggingSource = this.sourceList[i]; this.draggingSource.drag(event); return; } } } else { this.draggingSource.worldPosition = GeometryUtils.V2ToV3(event.getUILocation()); for (let i = 0; i < this.targetList.length; i++) { let target = this.targetList[i]; if (target.node.isValid && target.node.active && this.draggingSource.group == target.group) { target.draging(this.draggingSource,this.targetList[i].getComponent(UITransform).isHit(event.getUILocation()), event); } } this.draggingSource.draging(event); } } private onTouchEnd(event: EventTouch) { if (!this.draggingSource) {//没有进行拖拽 return; } this.draggingSource.drop(event); for (let i = 0; i < this.targetList.length; i++) { let target = this.targetList[i]; if (target.node.isValid && target.node.active && this.draggingSource.group == target.group && this.targetList[i].getComponent(UITransform).isHit(event.getUILocation())) {//如果分组相同且跟触摸点碰撞 target.drop(this.draggingSource, event); } } this.draggingSource.worldPosition = null; this.draggingSource = null; } private addSource(source: DragSource) { this.sourceList.push(source); } private addTarget(target: DragTarget) { this.targetList.push(target); } private removeSource(source: DragSource) { let index = this.sourceList.indexOf(source); index != -1 && this.sourceList.splice(index, 1); } private removeTarget(target: DragTarget) { let index = this.targetList.indexOf(target); index != -1 && this.targetList.splice(index, 1); } onDestroy() { this.touchNode.off(SystemEventType.TOUCH_MOVE, this.onTouchMove, this); this.touchNode.off(SystemEventType.TOUCH_END, this.onTouchEnd, this); DragSystem.thisObject = null; } public static addSource(source: DragSource) { this.thisObject.addSource(source); } public static addTarget(target: DragTarget) { this.thisObject.addTarget(target); } public static removeSource(source: DragSource) { this.thisObject && this.thisObject.removeSource(source); } public static removeTarget(target: DragTarget) { this.thisObject && this.thisObject.removeTarget(target); } public static onTouchEnd(event: EventTouch) { this.thisObject && this.thisObject.onTouchEnd(event); } public static get touchNode() { return this.thisObject.touchNode; } }