You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
274 lines
9.3 KiB
274 lines
9.3 KiB
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) {}
|
|
} |