import { Component, EventTouch, Label, Mask, Node, RichText, Tween, UITransform, Vec3, Widget, _decorator, log, tween, v3 } from "cc"; import { GEvent } from "db://assets/mx/module/event/GEvent"; const { ccclass, property } = _decorator; export enum BeginnerGuideType { DIANJI = 0, //点击 HUADONG = 1, //滑动 SHOW = 2, //展示 FREE = 3, //自由 TIME = 4, //时间 FULL = 5, //全屏 } @ccclass('BeginnerGuideManager') export default class BeginnerGuideManager extends Component { @property(Mask) maskNode: Mask = null; @property(Node) dianJiSpine: Node = null; @property(Node) huaDongSpine: Node = null; @property(Node) showSpine: Node = null; @property(Node) maskBlackNode: Node = null; @property(RichText) guideDesc: RichText = null; // graphics = null nodeArray: Node[] = []; registNode = null nextRegistNode = null finishCallBack = null curGuideType = BeginnerGuideType.DIANJI private _isTouchBound: boolean = false; // 缓存回调函数引用,保证 on/off 可正确解绑(避免内存/引用泄漏) private _onTouchStartHandler = (event: EventTouch) => { //目标节点不存在,拦截 if (!this.registNode) { event.preventSwallow = true; event.propagationStopped = true; return; } //目标区域存在,击中放行 let rect = this.registNode.getComponent(UITransform).getBoundingBoxToWorld(); if (this.curGuideType == BeginnerGuideType.SHOW || rect.contains(event.getUILocation())) { event.preventSwallow = true; event.propagationStopped = true; } else { event.preventSwallow = false; event.propagationStopped = false; } }; private _onTouchMoveHandler = (event: EventTouch) => { //目标节点不存在,拦截 if (!this.registNode) { event.preventSwallow = true; event.propagationStopped = true; return; } //目标区域存在,击中放行 let rect = this.registNode.getComponent(UITransform).getBoundingBoxToWorld(); if (this.curGuideType == BeginnerGuideType.SHOW || rect.contains(event.getUILocation())) { event.preventSwallow = true; event.propagationStopped = true; } else { event.preventSwallow = false; event.propagationStopped = false; } }; private _onTouchEndHandler = (event: EventTouch) => { //目标节点不存在,拦截 if (!this.registNode) { event.preventSwallow = true; event.propagationStopped = true; return; } if(Date.now() - this._time < 1000){ return; } if (this.curGuideType == BeginnerGuideType.FULL) { this.registNode = null; if (this.finishCallBack) { this.finishCallBack(); } return; } //目标区域存在,击中放行 let rect = this.registNode.getComponent(UITransform).getBoundingBoxToWorld(); if (this.curGuideType == BeginnerGuideType.DIANJI && rect.contains(event.getUILocation())) { this.registNode = null; event.preventSwallow = true; event.propagationStopped = true; if (this.nodeArray.length == 0) { if (this.finishCallBack) { this.finishCallBack(); } } else { let nextNode = this.nodeArray.shift(); this.nextNode(nextNode); } } }; bindNode() { this.node.on(Node.EventType.TOUCH_START, this._onTouchStartHandler, this); this.node.on(Node.EventType.TOUCH_MOVE, this._onTouchMoveHandler, this); this.node.on(Node.EventType.TOUCH_END, this._onTouchEndHandler, this); this._isTouchBound = true; } protected onEnable(): void { // 该节点可能会被隐藏/再显示;需要在 enable 时确保监听存在 if (!this._isTouchBound) { this.bindNode(); } } protected onDisable(): void { // 取消定时回调,避免节点回收后回调仍持有引用 this.unscheduleAllCallbacks(); this.node.off(Node.EventType.TOUCH_START, this._onTouchStartHandler, this); this.node.off(Node.EventType.TOUCH_MOVE, this._onTouchMoveHandler, this); this.node.off(Node.EventType.TOUCH_END, this._onTouchEndHandler, this); this._isTouchBound = false; } // LIFE-CYCLE CALLBACKS: // onLoad () {} onLoad() { this.fullNode = this.node.getChildByName('full'); if (this.fullNode) this.fullNode.active = false; // this.graphics = this.maskNode['_graphics'] // 监听改在 onEnable 里做,确保节点被重新激活后仍可点击 // this.schedule(() => { // if (this.maskBlackNode.opacity == 0) { // this.registNode = null // if (this.nodeArray.length == 0) { // this.node.removeFromParent() // this.node.destroy() // // EventMgr.emitEvent_custom(ryw_Event.swallowToucheFinishEvent); // } else { // let nextNode = this.nodeArray.shift() // this.nextNode(nextNode) // } // } // }, 5) } fullNode: Node = null; nextNode(registNode) { this.registNode = registNode if (this.curGuideType) { } else { this.dianJiSpine.worldPosition = registNode.worldPosition.clone().add(v3(10, 0, 0)) this._focusToNode(registNode) } } _time: number = 0; setBindNode(registNode: Node | Node[], finishCallBack: Function, guideDesc: string = '', xScale: number = 1, boxPosY: number = 500, nodeArray: Node[] = []) { this._time = Date.now(); this.guideDesc.string = guideDesc if (this.fullNode) this.fullNode.getChildByName("guideStr").getComponent(RichText).string = guideDesc this.finishCallBack = finishCallBack if (registNode instanceof Node) { this.registNode = registNode this.nodeArray = [] } else { this.registNode = registNode[0] this.nodeArray = registNode.splice(1) } this.dianJiSpine.worldPosition = this.registNode.worldPosition.clone().add(v3(10, 0, 0)) this.dianJiSpine.active = this.curGuideType == BeginnerGuideType.DIANJI this.huaDongSpine.active = this.curGuideType == BeginnerGuideType.HUADONG this.showSpine.active = this.curGuideType == BeginnerGuideType.SHOW this.maskNode.node.active = this.curGuideType != BeginnerGuideType.SHOW if (this.fullNode) this.fullNode.active = this.curGuideType == BeginnerGuideType.FULL; let yindaokuangNode = this.node.getChildByName("引导框"); let okBtn = yindaokuangNode.getChildByName('btnContinue'); okBtn.active = (this.curGuideType == BeginnerGuideType.TIME || this.curGuideType == BeginnerGuideType.SHOW) yindaokuangNode.active = this.curGuideType != BeginnerGuideType.FULL; this.guideDesc.node.scale_x = xScale Tween.stopAllByTarget(yindaokuangNode) if (this.fullNode) Tween.stopAllByTarget(this.fullNode) let tweenNode = this.fullNode && this.fullNode.active ? this.fullNode : yindaokuangNode; if (tweenNode == yindaokuangNode) tweenNode.scale = v3(0, 0, 1) tween(tweenNode) .to(0.4, { scale: v3(xScale, 1, 1) }) .call(() => { if (yindaokuangNode.active) okBtn.scale_x = xScale }) .start() // this.node.getChildByName('引导框').getChildByName('freeNode').active = this.curGuideType == BeginnerGuideType.FREE this._focusToNode(this.registNode) if (yindaokuangNode.active) yindaokuangNode.getComponent(Widget).bottom = boxPosY } _focusToNode(node) { this.scheduleOnce(() => { // this.graphics.clear(); if (node.isValid) { let rect = node.getComponent(UITransform).getBoundingBoxToWorld(); this.maskNode.node.worldPosition = node.worldPosition this.maskNode.node.getComponent(UITransform).width = rect.width// + 30 this.maskNode.node.getComponent(UITransform).height = rect.height// + 30 } }) } setOpacityMaskNode(num) { this.maskBlackNode.opacity = num } /**设置点击/滑动 */ setIsGuideClick(type: BeginnerGuideType, time: number = 0) { this.curGuideType = type //时间类型自动关闭 } showPlayerMoveGuide(bShow: boolean = false) { this.node.active = bShow this.maskNode.node.active = false this.node.getChildByName('引导框').active = false this.node.getChildByName('movePlayerTip').active = bShow this.showSpine.active = bShow if (!bShow) { GEvent.Ins.emit(GEvent.PlayMoveGuideFinish) } } showYinDao(bShow: boolean = false) { this.showSpine.active = bShow } onBtnContinueClick() { Tween.stopAllByTarget(this.node) this.registNode = null if (this.finishCallBack) { this.finishCallBack() } } // update (dt) {} }