refactor(map): 将新手指引动画从抖动改为缩放脉动
1. 替换原有的角度抖动动画为缩放脉动效果,调整了动画时长与参数 2. 统一重构了MissionCardComp和MissionHomeComp中的指引相关代码 3. 修正了代码中的空格、命名等格式问题
This commit is contained in:
@@ -226,8 +226,8 @@ export class MissionCardComp extends CCComp {
|
||||
|
||||
// ======================== 新手按钮指引 ========================
|
||||
|
||||
/** 新手按钮指引抖动最大角度(度) */
|
||||
private static readonly BUTTON_GUIDE_SHAKE_ANGLE: number = 10;
|
||||
/** 新手按钮指引脉动放大倍率 */
|
||||
private static readonly BUTTON_GUIDE_PULSE_SCALE: number = 1.15;
|
||||
/** 新手按钮指引每步时长(秒) */
|
||||
private static readonly BUTTON_GUIDE_STEP_DURATION: number = 4.2;
|
||||
/** 新手按钮指引气泡停留时长(秒) */
|
||||
@@ -929,7 +929,7 @@ export class MissionCardComp extends CCComp {
|
||||
|
||||
/**
|
||||
* 启动新手按钮指引:依次指引 英雄→装备→技能→药品 四个面板按钮。
|
||||
* 每步播放 bg/icon 循环抖动 + smalltip 气泡文案,
|
||||
* 每步播放 bg/icon 循环缩放脉动 + smalltip 气泡文案,
|
||||
* 已完成的步骤(smc.data.tip_done 对应键为 true)自动跳过,仅提醒 1 次。
|
||||
*/
|
||||
private playButtonGuide() {
|
||||
@@ -960,11 +960,11 @@ export class MissionCardComp extends CCComp {
|
||||
if (!step) return;
|
||||
const btn = step.getBtn();
|
||||
if (btn && btn.isValid) {
|
||||
this.playGuideShake(btn, true);
|
||||
this.playGuidePulse(btn, true);
|
||||
this.showGuideTip(btn, step.text);
|
||||
}
|
||||
this.scheduleOnce(() => {
|
||||
this.stopGuideShake(btn);
|
||||
this.stopGuidePulse(btn);
|
||||
// 本步提醒完成:记录完成标记(即使中止也只标记已播完的步骤)
|
||||
smc.data.tip_done[step.key] = true;
|
||||
this.nextButtonGuideStep();
|
||||
@@ -980,12 +980,12 @@ export class MissionCardComp extends CCComp {
|
||||
|
||||
/**
|
||||
* 中止指引(任务结束 / 组件销毁时调用):
|
||||
* 停止所有抖动动画、还原气泡文案并隐藏气泡。
|
||||
* 停止所有缩放脉动动画、还原气泡文案并隐藏气泡。
|
||||
*/
|
||||
private stopButtonGuide() {
|
||||
if (this.guideStepIndex < 0 && this.guideTipTextCache.size === 0) return;
|
||||
for (const step of this.guideSteps) {
|
||||
this.stopGuideShake(step.getBtn());
|
||||
this.stopGuidePulse(step.getBtn());
|
||||
}
|
||||
this.restoreGuideTipTexts();
|
||||
this.guideStepIndex = -1;
|
||||
@@ -1005,39 +1005,38 @@ export class MissionCardComp extends CCComp {
|
||||
}
|
||||
|
||||
/**
|
||||
* 对按钮 bg/icon 子节点播放循环抖动动画。
|
||||
* 使用 angle 往复 tween,不修改 position,避免与 Widget 布局冲突。
|
||||
* 对按钮 bg/icon 子节点播放循环缩放脉动动画。
|
||||
* 使用 scale 往复 tween,不修改 position,避免与 Widget 布局冲突。
|
||||
* @param btn 面板按钮节点(内部含 bg/icon 子节点)
|
||||
* @param repeat 是否无限循环(true = 循环抖动)
|
||||
* @param repeat 是否无限循环(true = 循环脉动)
|
||||
*/
|
||||
private playGuideShake(btn: Node, repeat: boolean) {
|
||||
const angle = MissionCardComp.BUTTON_GUIDE_SHAKE_ANGLE;
|
||||
private playGuidePulse(btn: Node, repeat: boolean) {
|
||||
const pulseScale = MissionCardComp.BUTTON_GUIDE_PULSE_SCALE;
|
||||
for (const name of ["bg", "icon"]) {
|
||||
const child = btn.getChildByName(name);
|
||||
if (!child || !child.isValid) continue;
|
||||
Tween.stopAllByTarget(child);
|
||||
child.angle = 0;
|
||||
// 单轮抖动约 0.94s(含间歇),节奏放慢避免高频晃动过刺眼
|
||||
let t = tween(child)
|
||||
.to(0.15, { angle: angle })
|
||||
.to(0.3, { angle: -angle })
|
||||
.to(0.15, { angle: 0 })
|
||||
.delay(0.34);
|
||||
child.setScale(1, 1, 1);
|
||||
// 单轮脉动约 0.6s,持续闪动与气泡停留节奏一致
|
||||
const pulseTween = tween(child)
|
||||
.to(0.3, { scale: new Vec3(pulseScale, pulseScale, 1) }, { easing: 'sineInOut' })
|
||||
.to(0.3, { scale: new Vec3(1, 1, 1) }, { easing: 'sineInOut' });
|
||||
if (repeat) {
|
||||
t = t.repeatForever();
|
||||
tween(child).repeatForever(pulseTween).start();
|
||||
} else {
|
||||
pulseTween.start();
|
||||
}
|
||||
t.start();
|
||||
}
|
||||
}
|
||||
|
||||
/** 停止按钮 bg/icon 抖动并复位角度 */
|
||||
private stopGuideShake(btn: Node | null) {
|
||||
/** 停止按钮 bg/icon 缩放脉动并复位缩放 */
|
||||
private stopGuidePulse(btn: Node | null) {
|
||||
if (!btn || !btn.isValid) return;
|
||||
for (const name of ["bg", "icon"]) {
|
||||
const child = btn.getChildByName(name);
|
||||
if (!child || !child.isValid) continue;
|
||||
Tween.stopAllByTarget(child);
|
||||
child.angle = 0;
|
||||
child.setScale(1, 1, 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -39,34 +39,34 @@ const { ccclass, property } = _decorator;
|
||||
export class MissionHomeComp extends CCComp {
|
||||
/** 调试日志开关 */
|
||||
debugMode: boolean = false;
|
||||
/** 开始游戏按钮节点(预留) */
|
||||
/** 开始游戏按钮节点(预留) */
|
||||
@property(Node)
|
||||
start_btn=null!
|
||||
start_btn = null!
|
||||
/** 主页按钮节点(预留) */
|
||||
@property(Node)
|
||||
home_btn=null!
|
||||
home_btn = null!
|
||||
/** 英雄图鉴按钮节点(预留) */
|
||||
@property(Node)
|
||||
hero_btn=null!
|
||||
hero_btn = null!
|
||||
/** 排行榜按钮节点 */
|
||||
@property(Node)
|
||||
rank_btn=null!
|
||||
rank_btn = null!
|
||||
/** 天赋按钮节点 */
|
||||
@property(Node)
|
||||
tals_btn=null!
|
||||
tals_btn = null!
|
||||
|
||||
|
||||
@property(Node)
|
||||
heros_page=null!
|
||||
heros_page = null!
|
||||
@property(Node)
|
||||
talents_page=null!
|
||||
talents_page = null!
|
||||
@property(Node)
|
||||
ranks_page=null!
|
||||
ranks_page = null!
|
||||
|
||||
// ======================== 新手指引(开始按钮抖动 + 气泡) ========================
|
||||
// ======================== 新手指引(开始按钮缩放脉动 + 气泡) ========================
|
||||
|
||||
/** 抖动最大角度(度) */
|
||||
private static readonly SHAKE_ANGLE: number = 10;
|
||||
/** 脉动放大倍率 */
|
||||
private static readonly PULSE_SCALE: number = 1.15;
|
||||
/** 气泡文案 */
|
||||
private static readonly TIP_TEXT: string = "点击开始游戏";
|
||||
/** 气泡弹出/停留/收起节奏(秒) */
|
||||
@@ -80,23 +80,23 @@ export class MissionHomeComp extends CCComp {
|
||||
|
||||
/** 注册任务结束事件 */
|
||||
protected onLoad(): void {
|
||||
this.on(GameEvent.MissionEnd,this.mission_end,this)
|
||||
this.on(GameEvent.MissionEnd, this.mission_end, this)
|
||||
}
|
||||
|
||||
/** 启动时显示主页 */
|
||||
start() {
|
||||
this.home_active()
|
||||
|
||||
// 新玩家:start_btn 抖动 + smalltip 气泡引导点击开始(仅 1 次)
|
||||
// 新玩家:start_btn 缩放脉动 + smalltip 气泡引导点击开始(仅 1 次)
|
||||
if (!smc.data.tip_done.start) {
|
||||
this.playStartGuide();
|
||||
}
|
||||
}
|
||||
|
||||
onEnable(){
|
||||
onEnable() {
|
||||
}
|
||||
|
||||
update(dt:number){
|
||||
update(dt: number) {
|
||||
|
||||
}
|
||||
|
||||
@@ -110,12 +110,12 @@ export class MissionHomeComp extends CCComp {
|
||||
start_mission() {
|
||||
mLogger.log(this.debugMode, 'MissionHomeComp', "start_mission")
|
||||
|
||||
// 点击开始后完成指引:停止抖动/气泡并记录完成标记
|
||||
// 点击开始后完成指引:停止缩放脉动/气泡并记录完成标记
|
||||
this.stopStartGuide();
|
||||
smc.data.tip_done.start = true;
|
||||
|
||||
oops.gui.open(UIID.Mission)
|
||||
this.node.active=false;
|
||||
this.node.active = false;
|
||||
|
||||
// 隐藏 mapLayer 下的 main 节点
|
||||
|
||||
@@ -124,24 +124,24 @@ export class MissionHomeComp extends CCComp {
|
||||
|
||||
// ======================== 新手指引实现 ========================
|
||||
|
||||
/** 启动指引:button 子节点循环抖动 + smalltip 气泡弹出 */
|
||||
/** 启动指引: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_btn 下名为 "Button" 的子节点循环缩放脉动(scale 往复,不触碰 position,避免与布局冲突)
|
||||
const pulseNode = this.getPulseNode();
|
||||
if (pulseNode) {
|
||||
Tween.stopAllByTarget(pulseNode);
|
||||
pulseNode.setScale(1, 1, 1);
|
||||
tween(pulseNode)
|
||||
.repeatForever(
|
||||
tween(pulseNode)
|
||||
.to(0.3, { scale: new Vec3(MissionHomeComp.PULSE_SCALE, MissionHomeComp.PULSE_SCALE, 1) }, { easing: 'sineInOut' })
|
||||
.to(0.3, { scale: new Vec3(1, 1, 1) }, { easing: 'sineInOut' })
|
||||
)
|
||||
.start();
|
||||
}
|
||||
|
||||
@@ -163,17 +163,17 @@ export class MissionHomeComp extends CCComp {
|
||||
}
|
||||
}
|
||||
|
||||
/** 停止指引:抖动复位、气泡收起并还原原文 */
|
||||
/** 停止指引:脉动复位、气泡收起并还原原文 */
|
||||
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 pulseNode = this.getPulseNode();
|
||||
if (pulseNode && pulseNode.isValid) {
|
||||
Tween.stopAllByTarget(pulseNode);
|
||||
pulseNode.setScale(1, 1, 1);
|
||||
}
|
||||
const tip = btn.getChildByName("smalltip");
|
||||
if (tip && tip.isValid) {
|
||||
@@ -186,10 +186,10 @@ export class MissionHomeComp extends CCComp {
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取 start_btn 下名为 "Button" 的子节点(即要抖动的节点)。
|
||||
* 获取 start_btn 下名为 "Button" 的子节点(即要播放缩放脉动的节点)。
|
||||
* @returns Button 子节点;未找到返回 null
|
||||
*/
|
||||
private getShakeNode(): Node | null {
|
||||
private getPulseNode(): Node | null {
|
||||
const btn = this.start_btn;
|
||||
if (!btn || !btn.isValid) return null;
|
||||
const node = btn.getChildByName("Button");
|
||||
@@ -234,25 +234,25 @@ export class MissionHomeComp extends CCComp {
|
||||
this.showPage(this.talents_page)
|
||||
}
|
||||
/** 任务结束回调:重新显示主页 */
|
||||
mission_end(){
|
||||
mission_end() {
|
||||
mLogger.log(this.debugMode, 'MissionHomeComp', "[MissionHomeComp]=>mission_end")
|
||||
this.home_active()
|
||||
}
|
||||
|
||||
/** 激活主页显示:刷新数据并显示节点 */
|
||||
home_active(){
|
||||
home_active() {
|
||||
// 任务结束回到主页:确保指引动画与气泡无残留
|
||||
this.stopStartGuide();
|
||||
this.uodate_data()
|
||||
this.hideAllPages()
|
||||
this.node.active=true
|
||||
this.node.active = true
|
||||
// 播放主页背景音乐,恢复默认音量
|
||||
oops.audio.volumeMusic = 1.0;
|
||||
oops.audio.playerMusicLoop("music/home")
|
||||
}
|
||||
|
||||
/** 更新主页显示数据(预留) */
|
||||
uodate_data(){
|
||||
uodate_data() {
|
||||
|
||||
}
|
||||
|
||||
@@ -260,7 +260,7 @@ export class MissionHomeComp extends CCComp {
|
||||
* 判断是否运行在微信小游戏环境。
|
||||
* @returns true = 微信小游戏环境
|
||||
*/
|
||||
isWxClient(){
|
||||
isWxClient() {
|
||||
return typeof wx !== 'undefined' && typeof (wx as any).getSystemInfoSync === 'function';
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user