refactor: 重构新手引导系统,替换旧引导方案
1. 删除旧的GuideComp组件和guide1引导预制体 2. 移除UIConfig中旧的Guide1配置项 3. 改用基于smc.data.tip_done的精细化单步引导 4. 为主页开始按钮新增首次启动引导逻辑 5. 优化引导状态管理,仅单次提示未完成步骤
This commit is contained in:
@@ -17,7 +17,7 @@
|
||||
* - GameEvent.MissionStart / MissionEnd —— 游戏生命周期事件
|
||||
* - UIID.Mission —— 战斗界面 ID
|
||||
*/
|
||||
import { _decorator, instantiate, Prefab, resources, Sprite, SpriteAtlas, UITransform ,Node} from "cc";
|
||||
import { _decorator, instantiate, Label, Prefab, resources, Sprite, SpriteAtlas, Tween, tween, UITransform, Vec3, Node } from "cc";
|
||||
import { ecs } from "../../../../extensions/oops-plugin-framework/assets/libs/ecs/ECS";
|
||||
import { CCComp } from "../../../../extensions/oops-plugin-framework/assets/module/common/CCComp";
|
||||
import { oops } from "../../../../extensions/oops-plugin-framework/assets/core/Oops";
|
||||
@@ -39,7 +39,9 @@ const { ccclass, property } = _decorator;
|
||||
export class MissionHomeComp extends CCComp {
|
||||
/** 调试日志开关 */
|
||||
debugMode: boolean = false;
|
||||
|
||||
/** 开始游戏按钮节点(预留) */
|
||||
@property(Node)
|
||||
start_btn=null!
|
||||
/** 主页按钮节点(预留) */
|
||||
@property(Node)
|
||||
home_btn=null!
|
||||
@@ -61,6 +63,20 @@ export class MissionHomeComp extends CCComp {
|
||||
@property(Node)
|
||||
ranks_page=null!
|
||||
|
||||
// ======================== 新手指引(开始按钮抖动 + 气泡) ========================
|
||||
|
||||
/** 抖动最大角度(度) */
|
||||
private static readonly SHAKE_ANGLE: number = 10;
|
||||
/** 气泡文案 */
|
||||
private static readonly TIP_TEXT: string = "点击开始游戏";
|
||||
/** 气泡弹出/停留/收起节奏(秒) */
|
||||
private static readonly TIP_STAY: number = 3.4;
|
||||
|
||||
/** 指引进行中标记(避免重复启动) */
|
||||
private guiding: boolean = false;
|
||||
/** 气泡原文缓存(指引结束后还原) */
|
||||
private guideTipOriginText: string = "";
|
||||
|
||||
|
||||
/** 注册任务结束事件 */
|
||||
protected onLoad(): void {
|
||||
@@ -70,10 +86,10 @@ export class MissionHomeComp extends CCComp {
|
||||
/** 启动时显示主页 */
|
||||
start() {
|
||||
this.home_active()
|
||||
|
||||
// 首次打开游戏打开guide1
|
||||
if (!smc.finish_guides.includes(1)) {
|
||||
oops.gui.open(UIID.Guide1);
|
||||
|
||||
// 新玩家:start_btn 抖动 + smalltip 气泡引导点击开始(仅 1 次)
|
||||
if (!smc.data.tip_done.start) {
|
||||
this.playStartGuide();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -93,19 +109,91 @@ export class MissionHomeComp extends CCComp {
|
||||
*/
|
||||
start_mission() {
|
||||
mLogger.log(this.debugMode, 'MissionHomeComp', "start_mission")
|
||||
|
||||
// 进入战斗后,关闭guide1
|
||||
if (!smc.finish_guides.includes(1)) {
|
||||
smc.finish_guides.push(1);
|
||||
oops.gui.remove(UIID.Guide1);
|
||||
}
|
||||
|
||||
|
||||
// 点击开始后完成指引:停止抖动/气泡并记录完成标记
|
||||
this.stopStartGuide();
|
||||
smc.data.tip_done.start = true;
|
||||
|
||||
oops.gui.open(UIID.Mission)
|
||||
this.node.active=false;
|
||||
|
||||
// 隐藏 mapLayer 下的 main 节点
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
// ======================== 新手指引实现 ========================
|
||||
|
||||
/** 启动指引:button 子节点循环抖动 + smalltip 气泡弹出 */
|
||||
private playStartGuide() {
|
||||
const btn = this.start_btn;
|
||||
if (!btn || !btn.isValid) return;
|
||||
if (this.guiding) return;
|
||||
this.guiding = true;
|
||||
|
||||
// start_btn 下名为 "Button" 的子节点循环抖动(angle 往复,不触碰 position,避免与布局冲突)
|
||||
const shakeNode = this.getShakeNode();
|
||||
if (shakeNode) {
|
||||
Tween.stopAllByTarget(shakeNode);
|
||||
shakeNode.angle = 0;
|
||||
tween(shakeNode)
|
||||
.to(0.15, { angle: MissionHomeComp.SHAKE_ANGLE })
|
||||
.to(0.3, { angle: -MissionHomeComp.SHAKE_ANGLE })
|
||||
.to(0.15, { angle: 0 })
|
||||
.delay(0.34)
|
||||
.repeatForever()
|
||||
.start();
|
||||
}
|
||||
|
||||
// smalltip 气泡:缓存原文后覆盖文案,弹出后保持显示直至点击
|
||||
const tip = btn.getChildByName("smalltip");
|
||||
if (tip) {
|
||||
const label = tip.getComponentInChildren(Label);
|
||||
if (label) {
|
||||
this.guideTipOriginText = label.string;
|
||||
label.string = MissionHomeComp.TIP_TEXT;
|
||||
}
|
||||
tip.active = true;
|
||||
Tween.stopAllByTarget(tip);
|
||||
tip.setScale(0, 0, 1);
|
||||
tween(tip)
|
||||
.to(0.15, { scale: new Vec3(1.1, 1.1, 1) }, { easing: 'quadOut' })
|
||||
.to(0.05, { scale: new Vec3(1, 1, 1) })
|
||||
.start();
|
||||
}
|
||||
}
|
||||
|
||||
/** 停止指引:抖动复位、气泡收起并还原原文 */
|
||||
private stopStartGuide() {
|
||||
if (!this.guiding) return;
|
||||
this.guiding = false;
|
||||
|
||||
const btn = this.start_btn;
|
||||
if (btn && btn.isValid) {
|
||||
const shakeNode = this.getShakeNode();
|
||||
if (shakeNode && shakeNode.isValid) {
|
||||
Tween.stopAllByTarget(shakeNode);
|
||||
shakeNode.angle = 0;
|
||||
}
|
||||
const tip = btn.getChildByName("smalltip");
|
||||
if (tip && tip.isValid) {
|
||||
Tween.stopAllByTarget(tip);
|
||||
const label = tip.getComponentInChildren(Label);
|
||||
if (label) label.string = this.guideTipOriginText;
|
||||
tip.active = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取 start_btn 下名为 "Button" 的子节点(即要抖动的节点)。
|
||||
* @returns Button 子节点;未找到返回 null
|
||||
*/
|
||||
private getShakeNode(): Node | null {
|
||||
const btn = this.start_btn;
|
||||
if (!btn || !btn.isValid) return null;
|
||||
const node = btn.getChildByName("Button");
|
||||
return node && node.isValid ? node : null;
|
||||
}
|
||||
|
||||
private showPage(page: Node) {
|
||||
@@ -153,6 +241,8 @@ export class MissionHomeComp extends CCComp {
|
||||
|
||||
/** 激活主页显示:刷新数据并显示节点 */
|
||||
home_active(){
|
||||
// 任务结束回到主页:确保指引动画与气泡无残留
|
||||
this.stopStartGuide();
|
||||
this.uodate_data()
|
||||
this.hideAllPages()
|
||||
this.node.active=true
|
||||
@@ -177,6 +267,8 @@ export class MissionHomeComp extends CCComp {
|
||||
|
||||
/** ECS 组件移除时销毁节点 */
|
||||
reset() {
|
||||
// 销毁前清理指引 tween,防止回调残留
|
||||
this.stopStartGuide();
|
||||
this.node.destroy();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user