引导系统基本完成,开始制作 引导步骤
This commit is contained in:
243
assets/script/game/map/GuideConComp.ts
Normal file
243
assets/script/game/map/GuideConComp.ts
Normal file
@@ -0,0 +1,243 @@
|
||||
import { _decorator, director, Node } from "cc";
|
||||
import { CCComp } from "../../../../extensions/oops-plugin-framework/assets/module/common/CCComp";
|
||||
import { GuideConfig, GuideConfigArray, GuideStepType, IGuideStep, findGuideByEndEvent, findGuideById, findGuideIndexById, findGuideByNumberId, finishCurrGuide, startGuide } from "../common/config/Guide";
|
||||
import { oops } from "../../../../extensions/oops-plugin-framework/assets/core/Oops";
|
||||
import { UIID } from "../common/config/GameUIConfig";
|
||||
import { GameEvent } from "../common/config/GameEvent";
|
||||
import { smc } from "../common/SingletonModuleComp";
|
||||
|
||||
const { ccclass } = _decorator;
|
||||
|
||||
/** 新手引导组件 */
|
||||
@ccclass('GuideConComp')
|
||||
export class GuideConComp extends CCComp {
|
||||
|
||||
/** Cocos Creator 组件生命周期方法 */
|
||||
onLoad() {
|
||||
console.log("[GuideConComp] onLoad 被调用");
|
||||
this.on(GameEvent.GuideStart, this.GuideStart, this);
|
||||
this.on(GameEvent.GuideEnd, this.GuideEnd, this);
|
||||
}
|
||||
|
||||
start() {
|
||||
this.init();
|
||||
}
|
||||
|
||||
/** 初始化引导管理器 */
|
||||
init() {
|
||||
console.log("[GuideConComp] init");
|
||||
this.initializeGuideProgress();
|
||||
// 移除自动启动第一个引导,所有引导都变成触发式
|
||||
// this.checkFirstGuide();
|
||||
}
|
||||
|
||||
/** 初始化引导进度数组 */
|
||||
private initializeGuideProgress() {
|
||||
// 确保 smc.guides 存在且长度匹配
|
||||
if (!smc.guides || smc.guides.length !== GuideConfigArray.length) {
|
||||
smc.guides = new Array(GuideConfigArray.length).fill(0);
|
||||
smc.syncGuide()
|
||||
console.log("[GuideCon] 初始化 smc.guides 为全0");
|
||||
}
|
||||
}
|
||||
GuideStart(e: any, data: any) {
|
||||
console.log("[GuideCon] 监听到开始引导 key: ", data);
|
||||
smc.current_guide=data
|
||||
if(this.isAllGuidesCompleted()) return
|
||||
const guide = findGuideByNumberId(data);
|
||||
if (guide) this.displayStep(guide);
|
||||
|
||||
}
|
||||
GuideEnd(e: any, data: any) {
|
||||
console.log("[GuideCon] 监听到结束引导 key: ", data);
|
||||
this.completeGuide(data)
|
||||
}
|
||||
|
||||
/** 显示引导步骤 */
|
||||
private displayStep(step: IGuideStep) {
|
||||
console.log("[Tutorial] 根据step类型显示引导", step);
|
||||
switch (step.type) {
|
||||
case GuideStepType.TIP:
|
||||
this.showTip(step);
|
||||
break;
|
||||
case GuideStepType.CLICK:
|
||||
this.showClickGuide(step);
|
||||
break;
|
||||
case GuideStepType.DRAG:
|
||||
this.showDragGuide(step);
|
||||
break;
|
||||
case GuideStepType.WAIT:
|
||||
this.showWaitGuide(step);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/** 信息引导 */
|
||||
private showTip(step: IGuideStep) {
|
||||
this.showGuideStepUI(step);
|
||||
this.scheduleOnce(() => {
|
||||
this.onStepCompleted(step);
|
||||
}, step.waitTime ?? 2000);
|
||||
}
|
||||
|
||||
/** 点击引导 */
|
||||
private showClickGuide(step: IGuideStep) {
|
||||
console.log("[Tutorial] 显示点击引导", step);
|
||||
if (!step.targetPath) {
|
||||
console.error("[Tutorial] 点击引导缺少目标路径");
|
||||
return;
|
||||
}
|
||||
|
||||
const targetNode = this.findTargetNode(step.targetPath);
|
||||
if (!targetNode) {
|
||||
console.error(`[Tutorial] 找不到目标节点: ${step.targetPath}`);
|
||||
return;
|
||||
}
|
||||
|
||||
console.log("[Tutorial] 开始点击引导UI", step.targetPath);
|
||||
this.showGuideStepUI(step, targetNode);
|
||||
}
|
||||
|
||||
/** 显示拖拽引导 */
|
||||
private showDragGuide(step: IGuideStep) {
|
||||
console.log("[Tutorial] 显示拖拽引导:", step.id);
|
||||
this.showGuideStepUI(step);
|
||||
}
|
||||
/** 显示等待引导 */
|
||||
private showWaitGuide(step: IGuideStep) {
|
||||
console.log("[Tutorial] 显示等待引导:", step.id);
|
||||
this.showGuideStepUI(step);
|
||||
|
||||
// 触摸监听器现在由 GuideSetpComp 管理
|
||||
}
|
||||
|
||||
/** 步骤完成回调 */
|
||||
private onStepCompleted(step: IGuideStep) {
|
||||
console.log(`[Tutorial] 步骤完成: ${step.id}`);
|
||||
finishCurrGuide(step.key)
|
||||
// 检查是否有下一个引导
|
||||
if (step.nextStep && step.nextStep.trim() !== "") {
|
||||
const nextGuide = findGuideById(step.nextStep);
|
||||
if (nextGuide && !this.isGuideCompleted(nextGuide.id)) {
|
||||
console.log(`[GuideCon] 自动开始下一个引导: ${nextGuide.id}`);
|
||||
startGuide(nextGuide.key)
|
||||
return;
|
||||
}
|
||||
}
|
||||
// 引导完成,关闭UI
|
||||
this.closeGuideStepUI();
|
||||
}
|
||||
|
||||
private completeAllGuide(){
|
||||
smc.guides = new Array(GuideConfigArray.length).fill(1);
|
||||
smc.syncGuide()
|
||||
}
|
||||
/** 完成指定引导 */
|
||||
private completeGuide(key:any) {
|
||||
smc.finishGuide(key);
|
||||
console.log(`[GuideCon] 引导 ${key} 已完成,进度数组: ${JSON.stringify(smc.guides)}`);
|
||||
}
|
||||
|
||||
/** 判断指定引导是否已完成 */
|
||||
private isGuideCompleted(guideId: string): boolean {
|
||||
const guideIndex = findGuideIndexById(guideId);
|
||||
if (guideIndex !== -1 && guideIndex < GuideConfigArray.length) {
|
||||
return smc.guides[guideIndex] === 1;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/** 判断所有引导是否已完成 */
|
||||
private isAllGuidesCompleted(): boolean {
|
||||
return smc.guides.every(stepStatus => stepStatus === 1);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/** 打开引导UI */
|
||||
private showGuideStepUI(step: IGuideStep, targetNode?: Node) {
|
||||
console.log(`[GuideCon] 开始打开UI: ${step.id}, uiId: ${UIID.Guide}`);
|
||||
|
||||
// 关闭之前的引导UI
|
||||
if (oops.gui.has(UIID.Guide)) {
|
||||
oops.gui.remove(UIID.Guide);
|
||||
console.log("[Tutorial] 关闭之前的引导UI", UIID.Guide);
|
||||
}
|
||||
|
||||
this.doOpenGuideStepUI(step, targetNode);
|
||||
}
|
||||
|
||||
doOpenGuideStepUI(step: IGuideStep, targetNode?: Node) {
|
||||
try {
|
||||
console.log("[Tutorial] 打开新的引导UI", UIID.Guide);
|
||||
oops.gui.open(UIID.Guide, {
|
||||
step: step,
|
||||
stepIndex: 0,
|
||||
totalSteps: 1,
|
||||
targetNode: targetNode,
|
||||
callbacks: {
|
||||
onStepComplete: this.onStepCompleted.bind(this),
|
||||
onComplete: this.completeAllGuide.bind(this)
|
||||
}
|
||||
});
|
||||
|
||||
console.log(`[GuideCon] 成功打开引导步骤UI: ${UIID.Guide}`);
|
||||
} catch (error) {
|
||||
console.error(`[GuideCon] 打开引导步骤UI失败: ${UIID.Guide}`, error);
|
||||
oops.gui.toast(step.tipText );
|
||||
}
|
||||
}
|
||||
|
||||
/** 关闭引导步骤UI */
|
||||
private closeGuideStepUI() {
|
||||
console.log("[GuideCon] 关闭引导步骤UI", UIID.Guide);
|
||||
oops.gui.remove(UIID.Guide);
|
||||
}
|
||||
|
||||
/** 查找目标节点 */
|
||||
private findTargetNode(path: string): Node | null {
|
||||
console.log(`[GuideCon] 开始查找目标节点: ${path}`);
|
||||
|
||||
const pathParts = path.split('/');
|
||||
let currentNode: any = director.getScene();
|
||||
|
||||
for (const part of pathParts) {
|
||||
if (!currentNode || !currentNode.getChildByName) {
|
||||
console.error(`[GuideCon] 节点 ${part} 不存在或没有getChildByName方法`);
|
||||
break;
|
||||
}
|
||||
|
||||
const childNode = currentNode.getChildByName(part);
|
||||
if (!childNode) {
|
||||
console.error(`[GuideCon] 找不到子节点: ${part}`);
|
||||
console.log(`[GuideCon] 当前节点 ${currentNode.name} 的子节点:`, currentNode.children.map(c => c.name));
|
||||
break;
|
||||
}
|
||||
|
||||
currentNode = childNode;
|
||||
}
|
||||
|
||||
if (currentNode) {
|
||||
console.log(`[GuideCon] 目标节点查找成功:`, currentNode.position, currentNode.getWorldPosition());
|
||||
return currentNode as Node;
|
||||
} else {
|
||||
console.error(`[GuideCon] 目标节点查找失败: ${path}`);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/** 重置引导 */
|
||||
resetGuide() {
|
||||
// 重置进度数组为全0
|
||||
smc.guides = new Array(GuideConfigArray.length).fill(0);
|
||||
smc.syncGuide()
|
||||
console.log("[GuideCon] 重置引导,进度数组重置为:", JSON.stringify(smc.guides));
|
||||
}
|
||||
|
||||
|
||||
/** 组件销毁时清理 */
|
||||
reset() {
|
||||
// this.guideProgress = []; // This line is removed
|
||||
oops.gui.remove(UIID.Guide);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user