import { DataEventId } from "../../data/GameData"; import GuideVO from "./GuideVO"; /** * @description 新手引导 * @author 邹勇 */ const { ccclass, property } = cc._decorator; @ccclass export default class Guide extends cc.Component { @property({ type: cc.Node, displayName: "显示区域" }) node_display: cc.Node = null; @property({ type: cc.Node, displayName: "点击区域" }) node_click: cc.Node = null; @property({ type: cc.Node, displayName: "背景" }) node_bg: cc.Node = null; @property({ type: cc.Node, displayName: "对话框" }) node_dialog: cc.Node = null; @property({ type: cc.Node, displayName: "手指" }) node_finger: cc.Node = null; @property({ type: cc.Sprite, displayName: "头像" }) node_head: cc.Sprite = null; @property({ type: cc.Node, displayName: "形象" }) node_person: cc.Node = null; @property({ type: cc.RichText, displayName: "对话内容" }) rich_dialog: cc.RichText = null; @property({ type: cc.RichText, displayName: "对话内容1" }) rich_dialog1: cc.RichText = null; @property({ type: cc.Node, displayName: "对话内容1" }) node_skip: cc.Node = null; private guides: GuideVO[]; private crtStep: number; private crtGuide: GuideVO; private targetNode: cc.Node; private event_data: string; /** 对话框对齐方式 上下左右中 */ private widgets: string[] = ['top', 'bottom', 'left', 'right', 'verticalCenter', 'horizontalCenter']; onLoad() { this.node_click.on(cc.Node.EventType.TOUCH_START, this.clickNodeClick, this); } start() { if (gData.guideData.crtID == null) { this.node.destroy(); return; } this.reset(); this.guides = gData.guideData.getGuidesByID(gData.guideData.crtID); this.crtStep = -1; this.nextStep(); } private nextStep() { this.crtStep++; this.crtGuide = this.guides[this.crtStep]; mk.guide.curGuideIdStr = gData.guideData.crtID + "_" + this.crtStep; this.updateGuide(); if(this.crtGuide && this.crtGuide.isShowSkip == "true"){ this.node_skip.active = true; }else{ this.node_skip.active = false; } mk.data.sendDataEvent(DataEventId.guide, `新手引导第${gData.guideData.crtID}_${this.crtStep}步完成`); } private updateGuide() { if (this.crtGuide == null) { this.close(); } else { this.node_display.getComponent(cc.Mask).type = this.crtGuide.display_type == 0 ? cc.Mask.Type.RECT : cc.Mask.Type.ELLIPSE; this.node_bg.opacity = 180; this.node_finger.opacity = 255; this.node_dialog.opacity = 255; this.targetNode = null; this.event_data = null; let [x, y, w, h] = [null, null, null, null]; //点击全屏下一步,显示区域不显示 || 点击区域下一步,并发送事件,显示区域读配置 if (this.crtGuide.click_rect == "all" || this.crtGuide.click_rect.indexOf("event") != -1) { //显示区域: display_rect为""表示全屏 if (this.crtGuide.display_rect.length == 0) { this.node_display.width = this.node_display.height = 0; } else { let arr = this.crtGuide.display_rect.split(":"); x = parseInt(arr[0]); y = parseInt(arr[1]); w = parseInt(arr[2]); h = parseInt(arr[3]); } if (this.crtGuide.click_rect == "all") { this.node_click.x = 0; this.node_click.y = 0; this.node_click.width = this.node.width; this.node_click.height = this.node.height; } else { this.event_data = this.crtGuide.id + "_" + (this.crtStep + 1); this.node_click.x = x; this.node_click.y = y; this.node_click.width = w; this.node_click.height = h; } } else {//点击按钮下一步,显示区域为配置的node,点击区域=显示区域 this.targetNode = cc.find("Canvas/" + this.crtGuide.click_rect); w = this.targetNode.width; h = this.targetNode.height; let pos = mk.game.getWorldPos(this.targetNode); x = pos.x; y = pos.y; // //lastStruggle // if (this.crtGuide && this.crtGuide.id == 2 && this.crtStep == 1) { // w = this.targetNode.parent.width; // h = this.targetNode.parent.height; // let pos1 = mk.game.getWorldPos(this.targetNode.parent); // x = pos1.x; // y = pos1.y - h / 2; // } if (this.crtGuide.btnEnable == '1') { //穿透点击目标节点时增加一个事件触发下一步,触发后移除 this.node_click.width = this.node_click.height = 0; let eventHandler = new cc.Component.EventHandler(); eventHandler.target = this.node; eventHandler.component = "Guide"; eventHandler.handler = "clickNodeClick"; this.targetNode.getComponent(cc.Button).clickEvents.push(eventHandler); } else { this.node_click.x = 0; this.node_click.y = 0; this.node_click.width = this.node.width; this.node_click.height = this.node.height; } } //显示区域由大到小动画 if (x != null && y != null && w != null && h != null) { if (this.crtGuide.display_type == 0) {//矩形选中框 //先重置 this.node_bg.x = this.node_bg.y = this.node_display.x = this.node_display.y = 0; this.node_display.width = this.node.width; this.node_display.height = this.node.height; //动画 cc.tween(this.node_display) .to(0.2, { x: x, y: y, width: w, height: h }, { onUpdate: () => { this.node_bg.x = -this.node_display.x; this.node_bg.y = -this.node_display.y; } }) .start(); } else { //先重置 this.node_bg.x = this.node_display.x = x; this.node_bg.y = this.node_display.y = y; this.node_display.width = this.node_display.height = this.node_bg.width = this.node_bg.height = this.node.height * 2; //动画 let radius = this.crtGuide.display_type; cc.tween(this.node_display) .to(0.2, { width: radius, height: radius }) .start(); } } //对话框位置 //全屏对齐 if (this.crtGuide.dialog_pos != null && this.crtGuide.dialog_pos.length > 0) { let arr = this.crtGuide.dialog_pos.split(":"); let wedgit = this.node_dialog.getComponent(cc.Widget); for (let i = 0; i < this.widgets.length; i++) { switch (i) { case 0: wedgit.isAlignTop = arr[i] != ""; break; case 1: wedgit.isAlignBottom = arr[i] != ""; break; case 2: wedgit.isAlignLeft = arr[i] != ""; break; case 3: wedgit.isAlignRight = arr[i] != ""; break; case 4: wedgit.isAlignVerticalCenter = arr[i] != ""; break; case 5: wedgit.isAlignHorizontalCenter = arr[i] != ""; break; } if (arr[i] != "") { wedgit[this.widgets[i]] = parseInt(arr[i]); } } wedgit.enabled = true; wedgit.updateAlignment(); } else {//显示区域偏移 let arr = this.crtGuide.dialog_pos1.split(","); let wedgit = this.node_dialog.getComponent(cc.Widget); wedgit.enabled = false; this.node_dialog.x = x + parseInt(arr[0]); this.node_dialog.y = y + parseInt(arr[1]); } //对话文字对齐方式 let a = this.crtGuide.dialog_alignment; this.rich_dialog.horizontalAlign = a == '0' ? cc.macro.TextAlignment.LEFT : (a == '1' ? cc.macro.TextAlignment.CENTER : cc.macro.TextAlignment.RIGHT); this.rich_dialog1.horizontalAlign = a == '0' ? cc.macro.TextAlignment.LEFT : (a == '1' ? cc.macro.TextAlignment.CENTER : cc.macro.TextAlignment.RIGHT); if (this.crtGuide.finger == "") { this.node_finger.active = false; } else { this.node_finger.active = true; let arr = this.crtGuide.finger.split(":"); this.node_finger.x = x + parseInt(arr[0]); this.node_finger.y = y + parseInt(arr[1]); } if (this.crtGuide.tr_form == 3 || this.crtGuide.tr_form == 4) { this.node_bg.active = false; if (this.node_click['_touchListener']) { this.node_click['_touchListener'].swallowTouches = false; } } else { this.node_bg.active = true; if (this.node_click['_touchListener']) { this.node_click['_touchListener'].swallowTouches = true; } } if (this.crtGuide.tr_form == 1 || this.crtGuide.tr_form == 3) { this.node_head.node.active = true; this.node_person.active = false; } else if (this.crtGuide.tr_form == 2 || this.crtGuide.tr_form == 4) { this.node_head.node.active = false; this.node_person.active = true; } if (mk.guide.curDes != '') { this.rich_dialog.string = mk.guide.curDes; this.rich_dialog1.string = mk.guide.curDes; mk.guide.curDes = ''; } else { this.rich_dialog.string = this.crtGuide.dialog; this.rich_dialog1.string = this.crtGuide.dialog; } } } async clickNodeClick() { mk.audio.playEffect("button"); cc.Tween.stopAllByTarget(this.node_display); console.log("clickNodeClick"); if (this.crtGuide.btnEnable == '1') { if (this.targetNode) { this.targetNode.getComponent(cc.Button).clickEvents.pop(); } } if (this.event_data) { //event_guide data:1_2 (1_2为新手引导的id) mk.event.emit("event_guide", this.event_data); } this.reset(); if (this.crtGuide.lag_next > 0) { await mk.time.WaitForSeconds(this.crtGuide.lag_next); } if (this.crtGuide.continue == "true") { if(mk.guide.continueCallBack) { let isContinue = mk.guide.continueCallBack(); if(isContinue) { --this.crtStep; } } } this.nextStep(); } /** 等待状态 透明不可点击 */ private reset() { this.node_display.width = 0; this.node_display.height = 0; this.node_bg.width = this.node.width; this.node_bg.height = this.node.height; this.node_bg.x = -this.node_display.x; this.node_bg.y = -this.node_display.y; this.node_bg.opacity = 0; this.node_click.width = 0 this.node_click.height = 0; this.node_finger.opacity = 0; this.node_dialog.opacity = 0 } private close() { mk.guide.close(); // this.node.destroy(); mk.guide.curGuideIdStr = null; if(mk.guide.continueCallBack) { mk.guide.continueCallBack = null; } console.log("closeGuide ======"); mk.ui.closePanel(this.node.name); } private clickSkip() { mk.audio.playEffect("button"); this.close(); mk.data.sendXYEvent("guide", `skip_${gData.guideData.crtID}_${this.crtStep}`); mk.data.sendDataEvent(DataEventId.guideSkip, `新手引导第${gData.guideData.crtID}_${this.crtStep}步跳过`); } protected onDestroy(): void { this.node_click.off(cc.Node.EventType.TOUCH_START, this.clickNodeClick, this); } }