Phaser 3 运行中的旋转补间动画更新时如何消除卡顿实现平滑过渡
Phaser 动态更新旋转动画避免卡顿的解决方案
卡顿原因
你直接修改tween.data[0].end属于操作tween内部未公开的私有属性,Phaser的tween在启动时已经缓存了起始角度、总角度差值、当前进度比例等核心参数,仅修改结束值不会触发内部参数的自动重算,下一帧渲染时会直接用新的结束值计算当前应渲染的角度,和上一帧的渲染值出现断层,就会产生跳变卡顿。
可用解决方案
方案1:使用Phaser官方提供的updateTo方法动态更新目标值(最简便)
Phaser3的Tween实例内置了updateTo方法,专门用于动态修改动画目标属性,内部会自动重算动画进度相关的所有参数,实现平滑过渡:
// 后端返回新角度后调用,第三个参数设为true表示自动重算进度,避免跳变 anim.updateTo('angle', 你的最终目标总角度, true)
注意:最终目标总角度要保证比当前容器的实时角度大,且多补N个360度,避免动画倒转
方案2:基于当前实时角度重建动画(兼容性最好)
如果你的Phaser版本较低没有updateTo方法,可以直接停掉旧动画,以当前容器的实时角度为起点创建新动画,完全避免跳变:
// 后端返回结果后执行 // 1. 停止原有动画 anim.stop(); // 2. 获取当前容器的实时渲染角度 const currentAngle = targetContainer.angle; // 3. 计算新的目标角度,加至少1圈360度保证旋转方向一致,不会倒转 const finalAngle = currentAngle + 360 * 2 + newStopAngle; // 这里多转2圈再停,可按需调整 // 4. 创建新的减速动画 const newAnim = scene.tweens.add({ targets: [targetContainer], angle: finalAngle, duration: WHEEL_ROTATION_DURATION * 0.6, // 可以按剩余旋转距离比例调整时长,更自然 ease: 'Cubic.easeOut', })
方案3:分阶段实现动画(用户体验最优)
如果后端接口响应时间不确定,可以拆分动画为两个阶段,完全避免等待接口时的空白或者跳变:
- 按钮点击后先启动无限循环的匀速旋转动画,让轮子先转起来
- 后端返回停止角度后,停掉匀速动画,以当前角度为起点,创建带减速效果的停止动画
// 点击按钮后先启动匀速旋转 const loopAnim = scene.tweens.add({ targets: [targetContainer], angle: '+=360', duration: 1000, // 匀速转一圈的时间,按需调整 repeat: -1, // 无限循环 ease: 'Linear' }) // 后端返回结果后执行 loopAnim.stop(); const currentAngle = targetContainer.angle; const finalAngle = currentAngle + 360 * 2 + newStopAngle; scene.tweens.add({ targets: [targetContainer], angle: finalAngle, duration: 2000, ease: 'Cubic.easeOut' })
内容的提问来源于stack exchange,提问作者JulienH
相关产品推荐
相关产品推荐

