refactor(mission): 优化节间过场表现与关卡流程

1. 新增地图滚动速度重置与背景动画加速逻辑,强化过场推进感
2. 重构节间过场流程,同步启动英雄归位与地图滚动
3. 调整关卡文本显示格式与字体大小,优化视觉体验
4. 新增全局移动锁控制英雄过场动画状态,修复动画残留问题
This commit is contained in:
panFD
2026-09-12 22:41:51 +08:00
parent 1b2545deec
commit 10e2c0d817
5 changed files with 74 additions and 28 deletions

View File

@@ -23,6 +23,7 @@ import { CCComp } from "../../../../extensions/oops-plugin-framework/assets/modu
import { smc } from "../common/SingletonModuleComp";
import { oops } from "../../../../extensions/oops-plugin-framework/assets/core/Oops";
import { HeroAttrsComp } from "../hero/HeroAttrsComp";
import { MoveSystem } from "../hero/MoveComp";
import { GameEvent } from "../common/config/GameEvent";
import { SkillTriggerType } from "../common/config/heroSet";
import { HeroViewComp } from "../hero/HeroViewComp";
@@ -223,6 +224,8 @@ export class MissionComp extends CCComp {
}
onDestroy() {
// 解除节间过场移动动画锁,避免泄漏到下一关
MoveSystem.transitionMoveLock = false;
// 退出关卡时恢复地图背景动画
smc.map.MapView.scene.mapLayer.playAnimations()
super.onDestroy();
@@ -296,12 +299,10 @@ export class MissionComp extends CCComp {
// ======================== 回合倒计时 ========================
/** 进入节间过场:恢复背景滚动 + 英雄归位(in_fight=false 触发编队排队),倒计时结束自动开下一节 */
/** 进入节间过场:停止倒计时状态(背景滚动与英雄归位已在节间过场启动时同步触发) */
private startWaveCountdown() {
this.waveCountdown = MissionComp.COUNTDOWN_TRANSITION;
this.isWaveCountdown = true;
// 节间过场:恢复地图背景滚动动画,表现玩家推进
smc.map?.MapView?.scene?.mapLayer?.playAnimations();
this.updateCountdownUI(true);
}
@@ -319,6 +320,8 @@ export class MissionComp extends CCComp {
this.lastTimeSecond = -1;
// 过场结束,停掉背景滚动(战斗中保持静止)
smc.map?.MapView?.scene?.mapLayer?.stopAnimations();
// 解除英雄移动动画锁:归位后恢复待机
MoveSystem.transitionMoveLock = false;
}
// ======================== 奖励与广告 ========================
@@ -1001,8 +1004,8 @@ export class MissionComp extends CCComp {
// Boss 节(末节)清场 → 本关通关,延迟弹结算(等死亡动画播完)
this.scheduleSettle(false, true);
} else {
// 非末节清场 → 不切暂停,延迟切 BattleEnd,由 autoNextPhase 进入节间过场自动推进下一节
this.scheduleSectionTransition();
// 非末节清场 → 立即启动节间过场(背景滚动 + 英雄归位同帧启动),自动连战下一节
this.beginSectionTransition();
}
return;
}
@@ -1065,19 +1068,21 @@ export class MissionComp extends CCComp {
}
/**
* 预约节间过场(非末节清场):延迟 SETTLE_DELAY 秒等死亡动画播完,再切 BattleEnd。
* 与 scheduleSettle 的区别:不置 pause、不弹结算,由 autoNextPhase 进入 PrepareStart 过场自动连战下一节。
* 启动节间过场(非末节清场):
* 1. 立即切出战斗(in_fight=false)→ 英雄触发编队排队、自动归位到左侧站位。
* 2. 同时恢复地图背景滚动,表现玩家推进(背景与英雄归位同帧启动,避免一先一后)。
* 3. 切 BattleEnd,2s 后由 autoNextPhase 进入 PrepareStart 过场倒计时,倒计时结束自动连战下一节。
*
* Why: 不等 SETTLE_DELAY 死亡动画,让"归位 + 背景滚动"在清场瞬间就启动,过渡更连贯。
*/
private scheduleSectionTransition() {
if (this._settleScheduled) return;
this._settleScheduled = true;
this.scheduleOnce(() => {
this._settleScheduled = false;
// 延迟期间局内状态可能已变化(如英雄刚好全灭、任务结束),兜底校验
if (!smc.mission.play || smc.mission.pause) return;
if (this.currentPhase !== MissionPhase.Battle) return;
this.changePhase(MissionPhase.BattleEnd);
}, MissionComp.SETTLE_DELAY);
private beginSectionTransition() {
smc.mission.in_fight = false;
smc.vmdata.mission_data.in_fight = false;
// 恢复地图背景滚动(与英雄归位同步启动,2 倍速表现推进)
smc.map?.MapView?.scene?.mapLayer?.playAnimations();
// 过场期间英雄保持移动动画:即使已归位也持续行军,地图停才回待机
MoveSystem.transitionMoveLock = true;
this.changePhase(MissionPhase.BattleEnd);
}
/**

View File

@@ -290,6 +290,8 @@ export class MissionHomeComp extends CCComp {
home_active() {
// 任务结束回到主页:确保指引动画与气泡无残留
this.stopStartGuide();
// 大厅地图恢复正常滚动速度(清除战斗节间过场的 4x 加速残留)
smc.map?.MapView?.scene?.mapLayer?.resetSpeed();
this.uodate_data()
this.hideAllPages()
this.refreshRedDots()

View File

@@ -86,14 +86,35 @@ export default class MapLayer extends Component {
return [this.bg_anm, this.bg_anm1, this.bg_anm2, this.bg_anm3, this.bg_anm4].filter((a): a is Animation => a !== null);
}
/** 背景滚动播放速度倍率(节间过场加快推进感) */
private static readonly SCROLL_SPEED = 4;
public playAnimations(name?: string): void {
this.animations.forEach(a => name ? a.play(name) : a.play());
this.animations.forEach(a => {
a.play(name);
// 加快背景滚动速度,强化节间"向前推进"的观感(AnimationState.speed 属性)
const clip = a.defaultClip;
if (clip) {
const state = a.getState(clip.name);
if (state) state.speed = MapLayer.SCROLL_SPEED;
}
});
}
public stopAnimations(): void {
this.animations.forEach(a => a.stop());
}
/** 恢复背景滚动为正常速度(1x):大厅/非过场时调用,清除过场加速残留 */
public resetSpeed(): void {
this.animations.forEach(a => {
const clip = a.defaultClip;
if (!clip) return;
const state = a.getState(clip.name);
if (state) state.speed = 1;
});
}
public pauseAnimations(): void {
this.animations.forEach(a => a.pause());
}