关于 v3-to-v4-migration
面向 Phaser v3 到 v4 升级的迁移指南,按破坏性变更和受影响的 API 梳理内容。帮助游戏开发者识别渲染、滤镜、摄像机、纹理、着色器等系统所需的代码更新。
主要功能
- 01说明 RenderNode 对 Pipeline 的替代
- 02介绍滤镜、遮罩和 tint API 变更
- 03描述摄像机和纹理坐标变化
- 04记录 DynamicTexture 与着色器更新
- 05列出光照、TileSprite、Graphics 和几何变更
适用场景
- 01规划 Phaser v3 到 v4 的升级
- 02将自定义 WebGL pipeline 改写为 render node
- 03更新使用遮罩、FX 或 tint API 的代码
- 04检查着色器、摄像机和纹理的迁移需求
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ phaserjs/ phaser --skill v3-to-v4-migration安装后在 Claude Code 中输入/v3-to-v4-migration确认已加载。
详细介绍
Phaser v3 到 v4 迁移指南
本指南涵盖了将 Phaser v3 项目升级到 Phaser v4 时需要更改的所有内容。它按照从影响最大的更改到较小的细节进行组织,因此你可以从上到下逐步处理。
相关技能: ../v4-new-features/SKILL.md, ../game-setup-and-config/SKILL.md, ../filters-and-postfx/SKILL.md
目录
- 渲染器:从管线到渲染节点
- Canvas 渲染器已弃用
- FX 和遮罩现在是过滤器
- 着色系统
- 摄像机系统
- 纹理坐标和 GL 方向
- DynamicTexture 和 RenderTexture
- Shader API
- GLSL 加载
- 光照
- TileSprite
- Graphics 和 Shape
- 几何:Point 被 Vector2 取代
- 数学常量
- 数据结构
- Round Pixels
- 已移除的游戏对象
- 已移除的插件和入口点
- 已移除的实用工具和 Polyfill
- Spine 插件
- 其他破坏性更改
- 迁移检查清单
1. 渲染器:从管线到渲染节点
Phaser v4 包含一个全新的 WebGL 渲染器。v3 的整个渲染管线已被替换。这是 v4 中最大的单一更改。
已移除的内容:
v3 的 Pipeline 系统已被完全移除。管线经常承担多种职责(例如 Utility 管线处理各种不同的渲染任务),并且每个管线都必须独立管理 WebGL 状态,导致一个管线可能破坏另一个管线的假设,从而产生冲突。
替代它的内容:
新的 RenderNode 架构。每个渲染节点处理单一的渲染任务,使系统更易于维护。所有渲染节点都有一个 run 方法,部分节点还有一个 batch 方法,用于在调用 run 之前从多个来源组装状态。
这对你意味着什么:
- 如果你的游戏只使用标准的 Phaser API(Sprites、Text、Tilemaps 等),新的渲染器应该可以透明地工作。
- 如果你在 v3 中编写了自定义 WebGL 管线,则需要将它们重写为渲染节点。使用
RenderConfig#renderNodes在启动时注册自定义渲染节点。 - 如果你直接访问了
WebGLRenderer内部属性,请注意许多内部属性已被移除或重构:WebGLRenderer.textureIndexes已移除。请改用glTextureUnits.unitIndices。WebGLRenderer#genericVertexBuffer和#genericVertexData已移除(释放约 16MB 的 RAM/VRAM)。BatchHandler渲染节点现在会创建自己的 WebGL 数据缓冲区。WebGLAttribLocationWrapper已移除。
- 不要在 Phaser v4 游戏中直接进行 WebGL
gl调用。这可能会在不更新内部WebGLGlobalWrapper的情况下更改 WebGL 状态,导致不可预测的行为。如果你需要直接访问 WebGL,请使用Extern游戏对象,它会在完成后重置状态。
2. Canvas 渲染器已弃用
Canvas 渲染器仍然可用,但应视为已弃用。Canvas 渲染不支持 v4 高级渲染功能中使用的任何 WebGL 技术。由于 WebGL 支持如今实际上已成为基线,我们建议所有新项目都使用 WebGL。
Canvas 保留了一个优势:27 种混合模式,而 WebGL 只有 4 种原生模式(NORMAL、ADD、MULTIPLY、SCREEN)。在 v4 中,新的 Blend 过滤器可以在 WebGL 中重现所有 Canvas 混合模式,不过它需要通过 CaptureFrame、DynamicTexture 或类似对象进行间接处理。
3. FX 和 Mask 现在是 Filter
对于依赖 FX 或 Mask 系统的 v3 用户来说,这是影响最大的变更之一。
变更内容:
FX(前置和后置)与 Mask 已统一为单一的 Filter 系统。一个 Filter 接收输入图像并产生输出图像,通常通过单个着色器实现。所有 filter 相互兼容。
与 v3 的主要区别:
- 不再有 preFX/postFX 之分。 Filter 分为 内部(仅影响对象本身)和 外部(在渲染上下文中影响对象,通常是全屏)两个列表。
- 不再有对象限制。 在 v3 中,只有特定对象支持 FX。在 v4 中,filter 可以应用于任何游戏对象或场景摄像机,包括
Extern对象。 BitmapMask已移除。 请改用新的Maskfilter。GeometryMask仅在 Canvas 中仍然可用。
已移除的派生 FX 及其替代方案:
| v3 FX | v4 替代方案 |
|---|---|
Bloom | Phaser.Actions.AddEffectBloom() |
Shine | Phaser.Actions.AddEffectShine() |
Circle | Phaser.Actions.AddMaskShape() |
Gradient | Gradient 游戏对象 |
ColorMatrix 变更:
ColorMatrix filter 将其颜色管理方法移到了 colorMatrix 属性上:
// v3
colorMatrix.sepia();
// v4
colorMatrix.colorMatrix.sepia();
Mask 迁移:
// v3 - BitmapMask
const mask = new Phaser.Display.Masks.BitmapMask(scene, maskObject);
sprite.setMask(mask);
// v4 - Mask filter
sprite.filters.internal.addMask(maskObject);
4. Tint 系统
Tint 系统已全面重写,采用了新的 API 并新增了混合模式。
已移除:
tintFill属性setTintFill()方法
替代方案:
- 使用新的
tintMode属性或setTintMode()方法来控制 tint 混合。 Phaser.TintModes枚举了可用的模式:MULTIPLY、FILL、ADD、SCREEN、OVERLAY、HARD_LIGHT。
如何转换你的代码:
// v3
sprite.setTintFill(0xff0000);
// v4
sprite.setTint(0xff0000).setTintMode(Phaser.TintModes.FILL);
其他 tint 变更:
tint和setTint()现在纯粹影响颜色设置。在 v3 中,调用这些方法会静默停用填充模式。- FILL 模式现在能正确处理部分透明度。
- BitmapText 的 tint 现在能正常工作。
5. 摄像机系统
摄像机矩阵系统已重写。如果你只使用标准的摄像机属性(scrollX、scrollY、zoom、rotation),你的代码应该无需更改即可运行。但是,如果你直接访问摄像机矩阵,则必须更新代码。
变更内容:
| v3 | v4 |
|---|---|
Camera#matrix = 位置 + 旋转 + 缩放 | Camera#matrix = 旋转 + 缩放 + 滚动(不含位置) |
| 滚动单独追加 | 滚动是 Camera#matrix 的一部分 |
| 无对应项 | Camera#matrixExternal = 仅位置 |
| 无对应项 | Camera#matrixCombined = matrix * matrixExternal |
如果你手动操作了滚动因子:
// v3
spriteMatrix.e -= camera.scrollX * src.scrollFactorX;
// v4
TransformMatrix.copyWithScrollFactorFrom(matrix, scrollX, scrollY, scrollFactorX, scrollFactorY);
其他摄像机变更:
GetCalcMatrix()现在接受一个额外的ignoreCameraPosition参数。GetCalcMatrixResults现在包含一个matrixExternal属性。
6. 纹理坐标和 GL 方向
Phaser v3 对纹理使用左上角方向,这导致了内部的不匹配(帧缓冲被倒置绘制,然后再翻转)。Phaser v4 全面使用 GL 方向,即 Y=0 位于底部。
需要采取的行动:
- 如果你使用压缩纹理,必须重新压缩,使 Y 轴从底部开始并向上递增。这通常在纹理压缩软件中作为"翻转 Y"选项提供。
- 标准图像纹理(PNG、JPG 等)会自动处理——无需操作。
- 如果你编写自定义着色器,请注意纹理坐标现在使用 GL 约定,即 Y=0 位于图像底部。
7. DynamicTexture 与 RenderTexture
在 v3 中,DynamicTexture 允许你直接定义批次并执行复杂的绘制操作。在 v4 中,许多此类复杂方法已被移除,转而使用标准渲染系统,由它自动处理批次。
破坏性变更: DynamicTexture 和 RenderTexture 现在必须调用 render() 才能执行所有已缓冲的绘制命令。此前,绘制命令会立即执行。
新能力:
DynamicTexture#preserve()会在渲染后保留命令缓冲区以供复用,让你可以重新渲染绘制不断变化的游戏对象的命令。DynamicTexture#callback()会插入一个回调,在命令缓冲区执行期间运行。DynamicTexture#capture比draw更准确地渲染游戏对象,它会捕获当前相机视图。RenderTexture.renderMode属性:"render"(像 Image 一样绘制)、"redraw"(在渲染循环期间更新纹理而不绘制)或"all"(两者兼具)。"redraw"模式支持在渲染循环中途更新纹理,以实现同帧着色器输出。TextureManager#addDynamicTexture现在有forceEven参数。
8. Shader API
Shader 游戏对象已被大幅重写。现有的 v3 着色器需要更新。
变更内容:
- 构造签名现在接收一个配置对象(
ShaderQuadConfig),而不是各个单独的参数。 - Shadertoy 风格的 uniform(分辨率、时间等)不再自动设置。如有需要,请将它们编码到你的配置中。
- 纹理坐标现在使用 GL 约定(Y=0 位于底部)。
- 新增
Shader#setUniform(name, value)方法,用于单独设置程序 uniform。 - 新增
Shader#renderImmediate方法,用于在常规渲染循环之外进行渲染。
9. GLSL 加载
Phaser 加载 GLSL 代码的方式已发生变化:
- 加载时,GLSL 代码不再被归类为 "fragment" 或 "vertex"。在新系统下,它可以是其中之一,或两者兼具。你需分别加载着色器,并在创建 Shader 时将它们组合起来。
- 自定义模板已被
#pragma预处理器指令取代,这些指令是合法的 GLSL,并与自动化语法检查器兼容。这些 pragma 会在编译前被移除。
10. 光照
光照已被简化和增强。
如何转换你的代码:
// v3 - Pipeline-based lighting
sprite.setPipeline('Light2D');
// v4 - Simple method call
sprite.setLighting(true);
其他光照变更:
- 许多游戏对象都支持光照:BitmapText、Blitter、Graphics、Shape、Image、Sprite、Particles、SpriteGPULayer、Stamp、Text、TileSprite、Video、TilemapLayer 和 TilemapGPULayer。
- 对象现在可以使用着色器投射自阴影,该着色器根据纹理亮度模拟来自表面特征的阴影。可在游戏全局或按对象进行配置。
- 光源现在有
z值来显式设置高度,取代了 v3 中基于游戏分辨率的隐式高度。 - 注意:光照会改变着色器,从而破坏渲染批次。
- 你也可以使用
ImageLight滤镜来实现基于图像的光照,但它与核心光照系统是分开的。
11. TileSprite
TileSprite 在内部已被重写,改用新的着色器,手动控制纹理坐标环绕,而不再依赖 WebGL 纹理环绕参数。
变更内容:
TileSprite不再支持纹理裁剪。- TileSprite 现在会分别对每个维度分配默认尺寸。
新能力:
- TileSprite 现在支持图集和精灵表中的纹理帧(v3 只能重复整个纹理文件)。
- 新增
tileRotation属性,允许旋转重复的纹理。 - 可正确处理压缩纹理、非 2 的幂纹理和 DynamicTexture(在 v3 中这些都有问题)。
12. 图形与形状
Graphics新增了pathDetailThreshold属性(也可作为游戏配置选项使用),它会跳过彼此距离在一定范围内的顶点,从而提升小区域内复杂曲线的性能。Grid形状重命名了属性:现在使用 stroke 而非 outline,以符合其他 Shape 对象的惯例。Grid 还新增了用于控制单元格之间间隙渲染,以及是在网格外部绘制轮廓还是仅在单元格之间绘制的选项。Rectangle现在支持圆角。
13. 几何:Point 被 Vector2 取代
Geom.Point 类及所有相关函数已被移除。请改用 Vector2。
方法替换速查表:
v3(Point) | v4(Vector2 / Math) |
|---|---|
Point.Ceil | Vector2.ceil |
Point.Floor | Vector2.floor |
Point.Clone | Vector2.clone |
Point.CopyFrom(src, dest) | dest.copy(src) |
Point.Equals | Vector2.equals |
Point.GetCentroid | Math.GetCentroid |
Point.GetMagnitude | Vector2.length |
Point.GetMagnitudeSq | Vector2.lengthSq |
Point.Invert | Vector2.invert |
Point.Negative | Vector2.negate |
Point.SetMagnitude | Vector2.setLength |
Point.Project | Vector2.project |
Point.ProjectUnit | Vector2.projectUnit |
Point.Interpolate | Math.LinearXY |
Point.GetRectangleFromPoints | Math.GetVec2Bounds |
所有几何类现在返回 Vector2 而非 Point:
以下类及其静态辅助函数(getPoint、getPoints、getRandomPoint、CircumferencePoint、Random 等)现在都返回 Vector2 实例:
Geom.CircleGeom.EllipseGeom.LineGeom.PolygonGeom.RectangleGeom.Triangle
如果你的代码中检查了 instanceof Phaser.Geom.Point,请将其更新为检查 Phaser.Math.Vector2。
14. 数学常量
| v3 | v4 | 说明 |
|---|---|---|
Math.TAU(曾是 PI / 2) | Math.TAU(现在是 PI * 2) | 值已改变! 现在才是数学上正确的 tau。 |
Math.PI2 | 已移除 | 请改用 Math.TAU。 |
| 无对应项 | Math.PI_OVER_2 | 新增常量,表示 PI / 2(也就是 v3 中 TAU 错误表示的值)。 |
需要采取的操作: 如果你在 v3 中使用 Math.TAU 时期望的是 PI / 2,请将其替换为 Math.PI_OVER_2。如果你使用了 Math.PI2,请将其替换为 Math.TAU。
15. 数据结构
Phaser.Struct.Set 已被原生 JavaScript Set 取代。iterateLocal 等方法已移除。请使用标准 Set 方法(forEach、has、add、delete 等)。
Phaser.Struct.Map 已被原生 JavaScript Map 取代。contains 和 setAll 等方法已移除。请使用标准 Map 方法(has、get、set、delete 等)。
16. 像素取整
roundPixels 游戏配置选项现在默认为 false(在 v3 中为 true)。其行为也已改进:
roundPixels仅在对象轴对齐且未缩放时生效,防止变换中的对象出现闪烁。- 如需按对象控制,请使用新的
GameObject#vertexRoundMode属性:"off"-- 从不取整。"safe"-- 仅当变换只涉及位置(无缩放/旋转)时取整。"safeAuto"(默认)-- 类似于"safe",但仅在相机启用了roundPixels时生效。"full"-- 始终取整(可能导致旋转精灵出现抖动,类似 PS1 风格)。"fullAuto"-- 类似于"full",但仅在相机启用了roundPixels时生效。
TransformMatrix#setQuad的roundPixels参数已被移除。
17. 已移除的游戏对象
Mesh和Plane已被移除。这些是受限的 3D 实现;未来计划提供正式的 3D 支持。
18. 已移除的插件和入口点
以下内容已被完全移除:
- Camera3D Plugin
- Layer3D Plugin
- Facebook Plugin 检测常量
phaser-ie9.js入口点(不再支持 IE9)
19. 已移除的工具函数与 polyfill
Create.GenerateTexture 以及所有 Create 调色板 / create 文件夹均已移除。因此,TextureManager.generate 也一并移除。
Math.SinCosTableGenerator 已移除。
所有旧版 polyfill 均已移除:
Array.forEachArray.isArrayAudioContextMonkeyPatchconsoleMath.truncperformance.nowrequestAnimationFrameUint32Array
现代浏览器已原生提供所有这些功能。
20. Spine 插件
Phaser 随附的 Spine 3 和 Spine 4 插件不再更新。请改用由 Esoteric Software 创建的官方 Phaser Spine 插件。
21. 其他破坏性变更
Shader#setTextures()现在会替换纹理数组,而不是向其追加。如果你之前多次调用它来逐步构建纹理,请改为一次性传入完整数组进行调用。DOMElement现在如果没有任何容器,将抛出错误。请确保你的 DOM 元素具有父容器。GameObject#enableLighting现在即使场景光照管理器未启用也可以设置。要让光照渲染,管理器仍必须启用,但该标志本身不再受此限制。- Gamepad
Button类 现在接受isPressed参数,以便在场景切换时正确初始化状态。 BatchHandlerConfig#createOwnVertexBuffer类型属性已移除。WebGLRenderer#genericVertexBuffer和#genericVertexData已移除(释放约 16MB 内存/显存)。
迁移检查清单
使用此检查清单来跟踪你的迁移进度:
- 更新
npm install phaser@4(或等效操作) - 将任何自定义 WebGL 管线替换为渲染节点
- 将
BitmapMask的用法替换为Mask滤镜 - 将已移除的 FX(
Bloom、Shine、Circle、Gradient)替换为对应的 Action/GameObject 等效项 - 更新
ColorMatrix调用(方法已移至.colorMatrix属性) - 将任何
setTintFill()调用替换为setTint().setTintMode(Phaser.TintModes.FILL) - 将
Geom.Point的用法替换为Vector2 - 更新
Math.TAU的用法(现在等于 PI * 2,而不是 PI / 2) - 将
Math.PI2替换为Math.TAU - 将
Phaser.Struct.Set替换为原生Set - 将
Phaser.Struct.Map替换为原生Map - 为
DynamicTexture/RenderTexture的用法添加render()调用 - 为新的 Y 轴方向重新压缩所有已压缩纹理
- 将任何直接访问
Camera#matrix的代码更新为使用新的矩阵系统 - 更新
Shader游戏对象以使用新的ShaderQuadConfig构造函数 - 更新 GLSL 加载代码(不再区分片段/顶点着色器,使用
#pragma指令) - 将
sprite.setPipeline('Light2D')替换为sprite.setLighting(true) - 更新光照高度代码以使用新的
z属性 - 移除任何
TileSprite纹理裁剪代码 - 更新
Grid形状代码(outline属性已重命名为stroke) - 移除任何
Mesh或Plane的用法 - 将任何 Phaser 随附的 Spine 插件用法替换为官方 Esoteric Software 插件
- 移除对
Create.GenerateTexture或TextureManager.generate的任何依赖 - 测试
roundPixels行为(现在默认值为false) - 移除对已移除的 polyfill、插件或入口点的任何用法
- 验证自定义着色器纹理坐标(Y=0 现在位于底部)