ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Phaser 3.60 Tween Manager 全面重构指南:链式补间、毫秒级 seek 与新事件体系

Phaser 3.60 Tween Manager 全面重构指南:链式补间、毫秒级 seek 与新事件体系 Phaser 3.60 Tween Manager 全面重构指南链式补间、毫秒级 seek 与新事件体系【免费下载链接】phaserPhaser is a fun, free and fast 2D game framework for making HTML5 games for desktop and mobile web browsers, supporting Canvas and WebGL rendering.项目地址: https://gitcode.com/gh_mirrors/ph/phaserPhaser 3.60 对 Tween补间系统进行了一次彻底重写目标是提升性能、解决历史遗留问题并统一补间事件与回调接口。本文以官方 3.60 变更日志 TweenManager.md 为主体结合仓库源码 src/tweens 下的 TweenManager、Tween、TweenChain 等实现系统讲解本次重构带来的破坏性变更、新增的链式补间能力、pause/resume 控制、数组插值动画等核心内容帮助你在升级到 3.60 后快速迁移旧代码并掌握新补间 API 的完整用法。为什么 3.60 要重写 Tween 系统官方变更日志明确指出Phaser 3.60 的 Tween 系统被重写是为了提升性能TweenBuilder在创建 TweenData 实例时被优化执行了更少的函数调用解决遗留问题例如seek在无限循环补间上会崩溃浏览器标签页的严重缺陷统一事件与回调将散落各处的 Scope 类配置项收敛为统一的callbackScope。从源码结构看本次重构将补间数据从普通对象提升为独立类src/tweens/tween/目录下新增了 TweenData.js、BaseTweenData.js、TweenChain.js 等模块并提供了Tween.initTweenData统一初始化入口见 Tween.js。整个补间系统以TweenManager默认 Scene 插件注册名为tweens见 TweenManager.js为中枢负责创建、更新、销毁所有补间。下面先从最需要关注的破坏性变更讲起——升级到 3.60 后这些变化会直接影响你现有代码的运行。破坏性变更清单升级前必读1. Timeline 被移除改用chain链式补间Tween Timeline时间线在 3.60 中被整体移除。官方给出的理由是Timeline 的实现方式容易引发一系列难以排查的时序 Bug。替代方案是新引入的chain方法用顺序播放的补间链实现同样的动画序列编排且不会有时间线那种计时问题。// 3.60 之前的写法Timeline——已失效 // this.tweens.timeline({ tweens: [ ... ] }); // 3.60 的新写法Tween Chain this.tweens.chain({ tweens: [ { targets: logo, x: 600, duration: 1000 }, { targets: logo, y: 400, duration: 800 }, { targets: logo, alpha: 0, duration: 500 } ] });从 TweenChainBuilder.js 的实现可以看到链上的每个 Tween 会按数组顺序依次播放还支持顶层targets作为默认值下发给没有指定自身 targets 的子补间。关于 chain 的详细用法见下文链式补间一节。2.seek从 0~1 归一化值改为毫秒值旧版Tween.seek(value)接收 0 到 1 之间的进度比例但它对无限循环infinite或重复repeat的补间无效甚至会导致浏览器标签页崩溃。新版seek改为接收毫秒// 3.60 之后seek 接收毫秒数 tween.seek(1500); // 跳到从补间开始算起的 1.5 秒处 tween.seek(); // 参数默认值为 0见源码 Tween.js#L502从 Tween.js 的 seek 实现 可以看出seek 会先将补间重置到初始值然后以delta默认 16.6ms为步长逐步迭代推进到目标位置。seek 期间默认不派发任何事件、不触发任何回调除非将第三个参数emit设为true。注意 seek 的进度计算会把整个补间的总时长包括 delay、loop、repeat都算进去例如一个时长 2 秒但循环 3 次的补间总时长是 6 秒seek(3000)会跳到整体进度的一半。3.duration、hold、repeat、repeatDelay不再接受函数创建补间时这 4 个属性只能传数字传函数会导致错误。唯一的例外是delay仍然支持函数以便兼容StaggerBuilder错开延迟的用法——这正是this.tweens.stagger(100)这类错开动画能工作的基础见 StaggerBuilder.js。4.getAllTweens更名为getTweensTweenManager.getAllTweens()在 3.60 中被重命名为 getTweens()功能完全相同返回当前 Tween Manager 中所有补间的引用数组浅拷贝可安全修改数组本身。const all this.tweens.getTweens(); // 3.60 新名称 // 旧this.tweens.getAllTweens();5.useFrames被移除补间全面基于毫秒Tween.useFrames属性以及对应的 Tween 配置项被彻底移除。3.60 起补间完全以毫秒为时间单位不再存在基于帧的计时模式。这也与 3.60 补间默认值 Defaults.js 中duration: 1000毫秒的定义保持一致。6. 回调参数签名统一onUpdate、onYoyo、onRepeat三类回调的参数签名被统一为tween, targets, key, current, previous, ...params其中tween补间实例本身targets补间的目标对象数组key当前正在补间的属性名字符串current属性的当前值previous属性的上一个值...params创建补间时通过onUpdateParams/onYoyoParams/onRepeatParams传入的额外参数。this.tweens.add({ targets: logo, x: 600, duration: 2000, onUpdate: (tween, targets, key, current, previous) { console.log(key, previous, -, current); } });7.stop移除了resetTo参数Tween.stop(resetTo)的resetTo参数被移除。调用stop后补间会立即进入待销毁状态。如果你只是想暂停请改用Tween.pause。8. 补间完成后自动销毁 新增persist标志3.60 起补间在播放完成后会由 Tween Manager自动销毁这能大幅减少陈旧引用stale references和内存占用。如果你希望补间在播放结束后仍然存活以便日后重播可以设置新的persist布尔标志const tween this.tweens.add({ targets: logo, x: 600, duration: 2000, persist: true // 播放结束后不被销毁可再次 play() }); // 之后任意时刻重播 tween.play();注意设置persist: true的代价是你必须自己负责销毁这个补间调用tween.destroy()否则它会常驻内存。persist已被加入保留关键字与默认值列表默认false见 ReservedProps.js 与 Defaults.js。源码层面TweenManager 的 step() 更新循环 会在每帧收集所有已完成的补间并统一销毁而 Tween.update() 在补间完成且persist为真时会将状态置为FINISHED而不是PENDING_REMOVE从而跳过销毁。9. Scope 类回调配置全部移除统一使用callbackScope所有形如onActiveScope、onCompleteScope、onLoopScope、onPauseScope、onRepeatScope、onResumeScope、onStartScope、onStopScope、onUpdateScope、onYoyoScope的配置项全部移除。改为设置callbackScope属性它会全局性地为所有回调设置this作用域也可以在创建后修改Tween.callbackScope。this.tweens.add({ targets: logo, x: 600, duration: 2000, callbackScope: myController, // 统一作用域 onComplete: function () { this.onLogoArrived(); // this myController } });新特性一链式补间Chained Tweens使用TweenManager.chain编排动画序列3.60 用链式补间替代了 Timeline作为编排多步骤动画的官方方案。调用 TweenManager.chain(config) 会创建一个TweenChain实例并立即加入 Tween Managerthis.tweens.chain({ // 可选顶层的 targets 会作为默认值下发给每个子补间 targets: logo, loop: 1, // 整条链循环 1 次共播放 2 遍 loopDelay: 500, // 链循环之间的间隔 tweens: [ { x: 600, duration: 1000, ease: Power1 }, { y: 400, duration: 800 }, { alpha: 0, duration: 500, delay: 200 } ] });TweenChain的实现位于 TweenChain.js其内部通过currentTween和currentIndex记录当前播放到哪一步nextTween()L479-L493在当前补间完成后自动推进到下一个。链支持loop/loopDelay循环、startDelay起始延迟、completeDelay完成延迟以及persist持久化。链上所有补间播完后默认整链自动销毁除非persist: true。从TweenChainBuilder的代码TweenChainBuilder.js可以看出链配置支持与单个补间相同的事件回调onStart、onLoop、onComplete等并可通过callbackScope统一作用域。查询链中的补间Tween.getChainedTweens()返回从当前补间开始、其后所有链式补间的数组TweenManager.getChainedTweens(tween)从给定补间开始返回整条链内部直接委托给tween.getChainedTweens()见 TweenManager.js。没有链式补间时返回空数组。随机属性值random(min, max)与int(min, max)3.60 允许把补间的目标属性值写成字符串随机表达式alpha: random(0.25, 0.75)——在[0.25, 0.75]之间随机取一个浮点数x: int(300, 600)——在[300, 600]之间随机取一个整数。this.tweens.add({ targets: logo, x: int(300, 600), // 随机整数终点 alpha: random(0.25, 0.75), // 随机浮点终点 duration: 2000 });这两种写法由 GetValueOp.js 解析字符串以random(开头时解析为随机浮点区间以int(开头时解析为随机整数区间格式非法会抛出invalid random() format错误。随机值是在补间数据初始化时生成的每次seek或重置补间都会重新取值。新特性二pause / resume 与新的回调3.60 为单个补间新增了完整的暂停/恢复控制Tween.pause()暂停补间派发PAUSE事件并触发onPause回调若设置Tween.resume()恢复被暂停的补间派发RESUME事件并触发onResume回调。配套新增了TweenOnPauseCallback配置键onPause与TweenOnResumeCallback配置键onResume均支持各自的onPauseParams/onResumeParams参数数组也可以通过 Tween.setCallbacks 方法追加。对应的事件常量定义在 src/tweens/events 目录下如 TWEEN_PAUSE_EVENT.js、TWEEN_RESUME_EVENT.js。const tween this.tweens.add({ targets: logo, x: 600, duration: 2000, paused: true, // 创建即暂停 onPause: () console.log(paused), onResume: () console.log(resumed) }); tween.play(); // 开始播放 tween.pause(); // 暂停触发 onPause tween.resume(); // 恢复触发 onResume注意两个相关的 Bug 修复paused: true创建后立即调用play()无法播放的 Bug 已修复#6005创建后立即暂停、之后无法恢复的 Bug 已修复#6169。相关修复还包括默认的_pausedState从INIT改为PENDING_ADD#5454。TweenManager 层面同样有全局的暂停/恢复pauseAll()/resumeAll()或直接读写布尔属性 TweenManager.paused。当paused为true时update() 会跳过整个更新步骤包括之后新建的补间。新特性三数组值插值与interpolation配置属性值可以是数组3.60 起补间的目标属性值可以是一个数值数组补间会沿数组执行插值this.tweens.add({ targets: logo, x: [ 100, 300, 200, 600 ], // 依次经过 100 → 300 → 200 → 600 duration: 4000 });指定插值算法通过interpolation配置项选择插值方法合法值包括linear线性bezier贝塞尔catmull或catmullromCatmull-Rom 样条也可以传入自定义函数。this.tweens.add({ targets: logo, x: [ 100, 300, 200, 600 ], interpolation: catmull, // 或 bezier / linear / 自定义函数 duration: 4000 });实现上TweenBuilder现在内部使用新的 GetInterpolationFunction.js 来解析该配置interpolation也已被加入保留关键字与默认值列表默认null见 ReservedProps.js 与 Defaults.js。scale快捷方式如果你在补间配置中指定scale而目标对象本身没有scale属性例如普通 GameObject补间会自动把该值同时应用到scaleX和scaleY。这是补间 GameObject 缩放的一条便捷捷径无需分别写两个属性// 3.60 便捷写法一条属性同时控制 scaleX 与 scaleY this.tweens.add({ targets: logo, scale: 0.5, duration: 1000 });该逻辑在 TweenBuilder.js 中实现当 key 为scale且目标没有自有scale属性时会生成scaleX与scaleY两条 TweenData。新特性四批量创建与更多 TweenManager 能力add/create支持配置数组TweenManager.add 与 TweenManager.create 现在可以传入一个补间配置对象数组为每个配置创建一个补间并返回补间数组当然也可以继续传单个配置对象。const [t1, t2] this.tweens.add([ { targets: logo, x: 600, duration: 1000 }, { targets: logo, alpha: 0, duration: 800 } ]);create与add的区别在于create只创建补间但不加入Tween Manager需配合 TweenManager.existing(tween) 手动加入才能播放。另有一个专门的 addMultiple(configs) 方法批量创建并添加。这两个方法都支持混入已有的 Tween / TweenChain 实例。新增TweenManager.resetreset(tween) 会将补间从所有内部数组中取出若不在则先加入seek 回起点并设为激活状态下一个帧开始播放。修复killTweensOf行为killTweensOf(targets)现在支持深层嵌套的数组作为 targets 参数修复 #6016修复了补间刚创建后立即调用killTweensOf(target)无法停止补间的问题#6173。底层实现中 getTweensOf 会先Flatten目标数组再逐个匹配killTweensOf 则直接调用每个命中补间的destroy()。时间缩放修复修复了补间和 Timeline 在基于帧的计时下不计算 Tween ManagertimeScale值的问题。3.60 中时间完全基于毫秒后Tween.update() 中的delta * this.timeScale * this.parent.timeScale同时应用了补间自身的timeScale与 Tween Manager 的全局timeScale保证setGlobalTimeScale对所有补间一致生效。其他值得注意的修复与内部重构setCallback参数可选调用Tween.setCallback(type, callback)时不传params不再报错修复 #6047。相关修复也确保了dispatchTweenEvent不再覆盖回调参数#5753使setCallback行为一致。repeathold结束时机修复了设置repeat与hold后补间在完成前会多停顿一次 hold 的问题——现在最后一次 repeat 结束后立即完成。Tween.reset与PENDING_REMOVE修复了补间处于PENDING_REMOVE状态时调用reset无法重启的问题#4793。Tween.stop(0)语义修复了stop(0)会额外运行一个 delta 才停止、导致补间并非真正 100% 重置的问题#5986。initTweenData统一初始化新增 Tween.initTweenData 负责所有 TweenData 与补间数值的初始化替代了原先分散在init和seek中的逻辑旧的内部方法calcDuration已移除时长计算并入initTweenData。该方法会自动调用通常不应直接手动调用。seek参数默认值seek的第一个参数toPosition毫秒现在默认值为 0不必再显式传入。升级迁移速查表旧 API3.60 之前新 API3.60说明tweens.timeline({ tweens: [...] })tweens.chain({ tweens: [...] })Timeline 移除改用链式补间tween.seek(0.5)0~1tween.seek(1500)毫秒seek 参数改为毫秒支持无限循环补间tweens.getAllTweens()tweens.getTweens()更名功能相同tween.stop(x)带 resetTotween.pause()/tween.stop()stop 不再接受 resetTo暂停用 pauseonUpdateScope等 10 个 Scope 配置callbackScope全局统一作用域useFrames: true配置移除补间全面基于毫秒duration/hold/repeat/repeatDelay 传函数仅限数字只有 delay 仍支持函数StaggerBuilder播放完成后补间常驻自动销毁 persist: true需持久化时显式设置 persist从整体来看3.60 的 Tween 系统重写是一次收紧核心、简化心智的升级移除 Timeline 与 useFrames 降低了计时复杂度链式补间、pause/resume、数组插值、随机值表达式和scale快捷方式则让日常动画编排更顺手。迁移时建议优先对照上文破坏性变更逐条检查现有代码再逐步尝试新特性。完整的 3.60 变更列表可查阅 CHANGELOG-v3.60.md补间相关的核心源码位于 src/tweens 目录包含 TweenManager.js、Tween.js、TweenChain.js 与 builders 下的一系列构建器仓库 tests/tweens 目录下还提供了对应的单元测试供参考验证。【免费下载链接】phaserPhaser is a fun, free and fast 2D game framework for making HTML5 games for desktop and mobile web browsers, supporting Canvas and WebGL rendering.项目地址: https://gitcode.com/gh_mirrors/ph/phaser创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表