PhaserJS 3.60中Tween动画进度条及回退功能实现问题
PhaserJS 3.60 Tween进度条与回退功能实现问题
PhaserJS 3.60的Tween系统支持通过seek方法实现进度条(seek bar)和动画回退功能,但你的代码存在多处逻辑错误,导致动画滞后、坐标及旋转角度异常。以下是问题分析和修正方案:
核心问题分析
- 全局时间计算逻辑错误:你用
scenesIndex.length * 100作为总时长基数,但每个Tween的延迟(delay)和时长(duration)是独立的,统一计算的totalTime无法匹配每个Tween的实际时间轴,导致seek位置偏差。 - seek方法参数误用:
tween.seek(totalTime, 16.6, true)中第三个参数skipRender设为true会跳过目标对象的状态更新,这是坐标异常的直接原因。 - 手动修改坐标的逻辑错误:
tween.getValue()默认返回第一个补间属性(此处为x)的值,你用它同时设置x和y,必然导致坐标混乱;且seek方法本身会自动更新目标状态,无需手动修改。 - 生命周期回调的Alpha设置错误:
onPause和onResume中都将Alpha设为0,导致动画恢复后无法看到对象,引发视觉异常。 - Tween创建时的参数大小写错误:
targets: TargetsObj应为targets: targetsObj,导致Tween绑定了错误的目标对象。
修正后的代码实现
1. 修复Tween创建方法
createTweensAnimation(targetsObj, imgPosFinal, angle, counter) { const tween = this.tweens.add({ targets: targetsObj, // 修正大小写错误 x: imgPosFinal.x, y: imgPosFinal.y, duration: 100, delay: counter * 100, persist: true, onStart: function() { targetsObj.setAngle(angle); targetsObj.setAlpha(1); }, onPause: function() { console.log("onPause"); // 暂停时保留当前视觉状态,无需强制隐藏 }, onResume: function() { console.log("onResume"); targetsObj.setAlpha(1); // 恢复时确保对象可见 } }) return tween }
2. 修复进度跳转逻辑
// 计算所有Tween的最大总时长(delay + duration),作为全局时间轴的总长度 const allTweens = Object.values(tweensArray).flat(); const maxTotalTime = Math.max(...allTweens.map(tween => tween.delay + tween.duration)); // 根据百分比计算目标全局时间点 const targetGlobalTime = maxTotalTime * (startSceneNumber / 100); allTweens.forEach((tween) => { tween.pause(); // 计算当前Tween对应的本地时间: // - 如果全局时间小于Tween的延迟,本地时间为0(动画未开始) // - 否则取全局时间减去延迟,且不超过Tween的时长 let localTime = Math.max(0, Math.min(tween.duration, targetGlobalTime - tween.delay)); // 执行seek,skipRender设为false,自动更新目标状态 tween.seek(localTime, 16.6, false); // 根据本地时间处理对象的初始/最终状态 if (localTime === 0) { // 动画未开始,隐藏对象到初始位置 tween.targets[0].setAlpha(0); tween.targets[0].x = -1000; tween.targets[0].y = -1000; } else if (localTime >= tween.duration) { // 动画已完成,强制设置到最终状态(避免seek精度问题) tween.targets[0].setAlpha(1); tween.targets[0].x = tween.data[0].end; tween.targets[0].y = tween.data[1].end; tween.targets[0].setAngle(tween.callbacks.onStart[0].args[0]); } else { // 动画进行中,保持当前状态 tween.targets[0].setAlpha(1); } // 根据目标时间决定是否恢复播放 if (targetGlobalTime < maxTotalTime) { tween.resume(); } });
回退功能实现
只需将startSceneNumber设置为更小的百分比(比如从50%跳到20%),重复执行上述修正后的进度跳转逻辑即可,Phaser的Tween支持向前和向后双向seek。
进度条联动建议
监听进度条的输入事件(如滑块拖动),实时获取当前百分比值,调用上述修正后的跳转逻辑,即可实现进度条与动画的同步控制。
内容的提问来源于stack exchange,提问作者daisuke-hongo
相关产品推荐
相关产品推荐

