资讯动态

Phaser 3.20 “Fitoria“ 版本核心特性深度解析:Video 游戏对象、Arcade 物理低帧率修复与 WebGL 纹理管线升级

发布时间:2026/9/19 2:04:20 来源:尧图企业网站定制
Phaser 3.20 Fitoria 版本核心特性深度解析Video 游戏对象、Arcade 物理低帧率修复与 WebGL 纹理管线升级【免费下载链接】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本文以官方版本更新日志 changelog/v3/3.20/CHANGELOG-v3.20.md 为骨架结合当前仓库src/与tests/下的源码实现深度剖析 Phaser 3.20.0代号 Fitoria2019 年 10 月 11 日发布引入的三大主线全新的 Video 游戏对象及其完整的加载/缓存/WebGL 纹理链路、Arcade Physics 在多物理步长低帧率场景下的三个关键缺陷修复以及遍布渲染、输入、瓦片地图、补间等系统的特性新增与 API 更新。读完本文你将掌握如何在 Phaser 3 中加载并播放本地或流媒体视频、如何把视频帧复用为纹理与着色器输入、如何规避浏览器自动播放限制同时理解 Arcade 物理步长模型的底层变化及对碰撞调试的影响。版本概览3.20.0 Fitoria3.20.0 是 Phaser 3 在 2019 年秋的一次功能型大版本核心成果包括Video 游戏对象Phaser 首次将视频提升为与 Sprite 平级的一等公民游戏对象支持本地文件、URL 与 MediaStream 三种来源Arcade Physics 步长修正修复帧率跌破 60 时即每帧执行多个物理步时出现的摩擦异常、物体陷入地面与静止速度非零三大问题WebGL 纹理管线扩充新增createVideoTexture/updateVideoTexture/createCanvasTexture/updateCanvasTexture并为纹理上传引入flipY控制大量易用性改进antialiasGL、自定义物理边界矩形、瓦片碰撞延迟更新、输入对象alwaysEnabled、UpdateList事件等。需要注意的是本仓库当前代码已演进至较新版本Video 类注释标记since 3.20.0的同时包含大量since 3.60.0、4.0.0的后续增强因此下文在讲解 3.20 引入能力时会同时给出当前仓库中可验证的实现细节并在涉及后续演进处加以说明。Video 游戏对象让视频像 Sprite 一样被使用基本用法预加载后播放更新日志给出的最小示例即预加载 创建两个步骤在 Video.js 类文档 中同样保留preload () { this.load.video(pixar, nemo.mp4); } create () { this.add.video(400, 300, pixar); }this.load.video由 VideoFile.js 通过FileTypesManager.register(video, ...)注册到加载器见 VideoFile.js。this.add.video则对应 VideoFactory.js。创建出来的 Video 是一个标准游戏对象混入了 Alpha、BlendMode、Depth、Flip、Mask、Origin、Tint、Transform、Visible 等全部常用组件见 Video.js因此缩放、旋转、裁剪、着色、交互、物理体等操作与 Sprite 完全一致。运行时加载跳过预加载视频是少数不必预加载的资源类型。创建对象后直接调用loadURL即可在运行时加载见 Video.jscreate () { this.add.video(400, 300).loadURL(assets/aliens.mp4); }loadURL内部会调用Device.Video.getVideoURL(urls)做格式探测详见下文设备视频格式检测若浏览器不支持给定格式则输出控制台警告。播放控制与常用方法Video 提供了完整的播放控制 API均可链式调用对应源码见 Video.js方法作用源码位置play(loop, markerIn, markerOut)开始播放支持循环与起止标记Video.jsstop(emitStopEvent)停止播放并清理事件监听Video.jssetPaused(value)/pause()暂停/恢复Video.jsseekTo(value)按 01 比例跳转Video.jssetCurrentTime(seconds)按秒跳转支持2/-2.5相对位移Video.jsgetCurrentTime()/getDuration()/getProgress()查询播放时间、总时长、进度直播流无时长时进度返回 -1Video.jssetMute(value)/isMuted()静音控制Video.jsaddMarker(key, in, out)/playMarker(key, loop)/removeMarker(key)把一段视频拆分为可独立播放的序列Video.jssnapshot(width, height)/snapshotArea(...)截取当前帧为 CanvasTextureVideo.jssaveTexture(key, flipY)把视频注册到 Texture Manager供其他对象/着色器使用Video.jschangeSource(key)不销毁视频元素的前提下换源已解锁的自动播放状态得以保留Video.js视频事件Video 游戏对象通过Phaser.GameObjects.Events命名空间暴露完整生命周期事件对应文件位于 src/gameobjects/events/VIDEO_PLAY、VIDEO_PLAYING、VIDEO_CREATED、VIDEO_COMPLETE、VIDEO_LOOP、VIDEO_STOP、VIDEO_ERROR、VIDEO_LOCKED、VIDEO_UNLOCKED、VIDEO_UNSUPPORTED、VIDEO_SEEKING、VIDEO_SEEKED、VIDEO_STALLED、VIDEO_METADATA、VIDEO_TEXTURE。其中VIDEO_LOCKED/VIDEO_UNLOCKED与自动播放策略密切相关当play()的 Promise 以NotAllowedError被拒绝时Phaser 会进入touchLocked状态并发出VIDEO_LOCKED见 Video.js。自动播放限制与 noAudio 参数浏览器对带音频视频的自动播放有严格策略。更新日志与 Video.js 类文档 一致地给出解法声明视频不含音轨使mutedautoplay生效从而绕过用户交互门槛preload () { this.load.video(pixar, nemo.mp4, true); // 第三个参数 noAudio true } create () { this.add.video(400, 300).loadURL(assets/aliens.mp4, true); }从实现看noAudio为true时loadHandler会设置video.muted true、video.defaultMuted true并写入autoplay属性见 Video.js。即便视频实际含音频设置noAudio也能立即播放只是声音不会启动。此外Phaser 在touchLocked期间会以retryInterval默认 500ms为间隔在preUpdate中反复重试play()见 Video.js一旦用户首次交互完成即自动续播。透明视频与 WebM 支持更新日志指出只要视频以带 alpha 通道的 WebM 编码且浏览器支持 WebM 播放即可在游戏中呈现全透明效果。这在特效演出如粒子状火焰、无背景动画角色场景中非常实用。需要留意的是并非所有浏览器都支持 WebM 透明通道跨浏览器发布前应做兼容性验证。加载器层面的特殊设计VideoFile 不做真实下载值得深入理解的是VideoFile的load()方法并不发起 XHR 请求而是解析出最终 URL 后直接标记FILE_LOADED并推进队列见 VideoFile.js。真实的视频数据由 Video 游戏对象在播放时才通过video元素拉取。onProcess()则把{ url, noAudio, crossOrigin }组装进file.data见 VideoFile.js供游戏对象后续使用。这一点在测试 tests/loader/filetypes/VideoFile.test.js 中被完整验证包括文件类型为video、键名与noAudio默认值、配置对象形式传参、baseURL前缀拼接、绝对 URL 不拼接、load()后状态为FILE_LOADED且调用loader.nextFile、数组批量注册等十余个断言用例。格式自动选择多格式 URL 数组由于各浏览器支持的视频格式不同更新日志和 VideoFile.js 的video方法文档 都建议一次提供多种格式加载器会依据浏览器能力自动挑选第一种可播放的格式this.load.video(intro, [ video/level1.mp4, video/level1.webm, video/level1.mov ]); // 或使用配置对象 this.load.video({ key: intro, url: [ video/level1.mp4, video/level1.webm, video/level1.mov ], noAudio: true });视频生态底层链路缓存、设备检测与 WebGL 纹理3.20 为视频支撑起一条完整的底层链路更新日志列出的相关改动都能在当前仓库中找到对应实现。Cache.video新的全局视频缓存CacheManager新增video缓存实例用于存放已加载视频的元数据URL、noAudio、跨域设置见 src/cache/CacheManager.js。Video 游戏对象的load(key)正是通过this.scene.sys.cache.video.get(key)取回数据再转交loadHandler见 Video.js。TextureSource.isVideo 与 flipYTextureSource新增布尔属性isVideo当纹理源由HTMLVideoElement支撑时置位见 src/textures/TextureSource.js同时新增flipY属性与setFlipY()方法控制 WebGL 纹理上传时的UNPACK_FLIP_Y_WEBGL标志见 TextureSource.js。若视频在着色器或自定义渲染器中显示为上下颠倒可通过Video.saveTexture(key, false)或直接翻转该标志解决。WebGLRenderer 的视频/画布纹理方法更新日志新增的四个 WebGL 渲染器方法均可验证createVideoTexture(srcVideo, noRepeat, flipY)WebGLRenderer.jsupdateVideoTexture(srcVideo, dstTexture, flipY, noRepeat)WebGLRenderer.jscreateCanvasTexture/updateCanvasTexture基于 Canvas 元素创建/更新 WebGL 纹理createTexture2D与canvasToTexture新增可选flipY参数WebGLRenderer.js、WebGLRenderer.js在渲染层面VideoWebGLRenderer.js 与 VideoCanvasRenderer.js 分别承载两套渲染路径对应的单元测试位于 tests/gameobjects/video/。设备视频格式检测与属性重命名更新日志将Device.Video的一系列属性统一去掉了Video后缀以对齐音频设备的命名风格3.20 前3.20 起h264Videoh264hlsVideohlsmp4Videomp4oggVideooggvp9Videovp9webmVideowebm在 src/device/Video.js 中这些布尔属性在启动阶段通过videoElement.canPlayType(...)逐一探测ogg/theora、h264、mov/quicktime、m4v、webm vp8/vp9、HLS并暴露getVideoURL(urls)工具函数传入 URL 或 URL 数组返回第一个浏览器可播放条目的{ url, type }blob:与data:前缀的 URL 会被直接放行全部不支持时返回null见 Video.js设备模块。视频复用为纹理与着色器输入更新日志强调视频可保存进 Texture Manager供其他游戏对象作为纹理使用甚至可作为着色器的sampler2D输入。核心方法是saveTexture(key, flipY)见 Video.jsvar vid this.add.video(400, 300, intro); vid.play(true); vid.saveTexture(movie); // 其他 Sprite 直接使用该纹理 this.add.image(600, 300, movie);当前实现还支持snapshot()saveSnapshotTexture(key)把某一帧截图发布为纹理见 Video.js适合做海报帧或暂停画面。Arcade Physics低帧率下的多步长缺陷修复更新日志指出当帧率低于 60技术上只要每帧执行多个物理步物理 FPS 高于 60 也会触发时Arcade 物理暴露出三个问题摩擦异常移动平台上的物体被推到平台前缘并卡住物体陷入地面相机锁定玩家时表现为整个世界上下抖动静止速度非零物体陷入地面后rest velocity不为 0干扰调试与逻辑判断。修复一Body.prevFrame 区分帧长与步长位移Body.prevFrame是新增向量用于区分每帧位移与每步位移——低帧率下每帧可能执行多个物理步见 Body.js。同时Body._reset标志被移除改为直接检查Body.moves原标志只在moves为 true 时置位且从不复位。Body.step中对prev的复位修复了摩擦问题。修复二postUpdate 不再改写步长数据Body.postUpdate不再设置_dx、_dy与prev使其保持最后一次物理步结束时的状态。这使增量方法delta 系列真正遵循其文档语义提供的是步级数据而非帧级数据。需要留意的是由于每帧可能执行多个步若未基于碰撞等物理事件编写逻辑只能读到最近一步的数值无法逐帧回溯每一步。修复三World.postUpdate 清零 stepsLastFrameArcade.World新增stepsLastFrame归零逻辑见 World.js 及其在 World.js 附近的判断此前该计数器从不归零导致即使可以跳帧也每帧至少跑一轮物理白白消耗性能。修复四移除 TileCheckX / TileCheckY 的 blocked 检查移除瓦片碰撞检查中的blocked判断。原逻辑在物体靠上地面后阻止重复检查但当每帧多步执行时物体在第二步起会再次加速、地面却不再阻挡最终陷入地面一段距离。移除该检查后陷入地面与静止速度问题一并解决。更新日志同时指出这使同一帧内可能发生多次瓦片检查但物体单帧同时撞上两块不同地面的情况极其罕见代价可接受。这些更新组合修复了 issue #4732 与 #4672来自 GameFroot 团队BenjaminDRichards 等的贡献。相关新特性自定义物理边界与物理相关的另一项新特性是自定义边界矩形ArcadePhysics.Body.setBoundsRectangle(bounds)为单个 Body 指定自定义碰撞边界替代默认的 World bounds见 Body.jsBody.customBoundsRectangle属性保存该自定义边界Body.jsArcade Physics Group 配置对象新增customBoundsRectangle可统一为组内所有 Body 设置。新增特性集锦GameConfig.antialiasGL新布尔配置antialiasGL允许在创建 WebGL 上下文时独立设置antialias而不影响后续创建的纹理或 canvas 的 CSS见 src/core/Config.js。注意pixelArt: true会自动把antialias与antialiasGL都置为false并把roundPixels置为true便于像素画风格的清晰缩放Config.js。InteractiveObject.alwaysEnabledInteractiveObject新增布尔属性alwaysEnabled使交互游戏对象即使不可见或不渲染也能持续接收输入事件适用于隐形热区类设计。Bob.setTintBlitter 的Bob对象新增setTint方法由 rexrainbow 贡献Blitter WebGL 渲染器据此为单个 Bob 着色适合粒子密集场景中的低成本变色。UpdateList 事件与 ProcessQueue 重构UpdateList现在会在子对象加入/移除时发出add与remove两个事件。更深远的变化是UpdateList改为继承ProcessQueue结构体见 src/gameobjects/UpdateList.js原有的_list等私有属性消失。ProcessQueue本身升级为事件发射器新增PROCESS_QUEUE_ADD/PROCESS_QUEUE_REMOVE事件见 src/structs/ProcessQueue.js 与 ProcessQueue.js并提供removeAll()与length属性。这同时修复了场景结束时列表项残留的内存管理问题issue #4721。Tilemap.setCollision 的 updateLayer 参数Tilemap.setCollision新增可选布尔参数updateLayer为true时更新图层内所有瓦片的碰撞设置为false时跳过适用于瓦片未变、仅切换碰撞标志的场景可带来显著性能提升——尤其是程序化生成、无限地图、多人同步或超大型动态瓦片地图见 SetCollision.js。该参数同样被加入SetCollisionBetween与DynamicTilemapLayer.setCollision见 SetCollisionBetween.js。WebGL flipY 参数族除视频相关方法外createTexture2D与canvasToTexture都新增了可选的flipY参数用于控制UNPACK_FLIP_Y_WEBGL标志与TextureSource.flipY/setFlipY形成完整控制链。重要更新与缺陷修复精选更新日志中的 Updates 与 Bug Fixes 部分信息量极大这里选取与日常开发最相关的几项着色器纹理初始化Shader.setRenderToTexture()改为立即绘制一次到纹理避免纹理空白一帧容器 alpha 象限Container 现在可设置topLeft / topRight / bottomLeft / bottomRight四角 alpha并传递给支持该能力的子对象如 Sprite修复 issue #4714Canvas 渲染器抗锯齿统一Canvas 渲染器新增antialias属性所有使用 Set Transform 的游戏对象BitmapText、Text、Sprite、RenderTexture 等在启用 pixel art 时都能正确缩放修复 issue #4701Tween.getValue 多目标修复支持指定 TweenData 索引取值此前只返回第一个 TweenDataissue #4717Tween.updateTo也不再只更新第一个匹配目标issue #4763GameObject.setTexture / TextureManager.get两者均可接受字符串键或 Texture 实例SceneManager.stop(data)SceneManager.stop与ScenePlugin.stop新增可选data参数随场景 shutdown 一并传递issue #4510MouseManager.target可传字符串或HTMLElement实例issue #4353拖拽缩放补偿InputPlugin.processDragMove发出的dragX / dragY现在会补偿父容器缩放缩放容器内的子对象拖拽速度恢复正常RenderTextureresize会同步更新 CanvasTexture 尺寸fill在绘制前正确设置相机setSize自动更新displayOrigin触摸事件onTouchStart / onTouchEnd / onTouchMove会先检查event.cancelable再调用preventDefault消除滚动中无法取消 touchstart 的控制台报错Sprite 批处理光照每个 Sprite 使用各自的uInverseRotationMatrix修复多 Sprite 不同旋转时的光照错误ScaleManager.startFullscreen改为检查调用是否返回 Promise 再等待解析修复 Edge 的运行时警告issue #4795Matter.js修复Body.update中 part 角度设置错误、MatterPhysics.shutdown在 Game.destroy 过程中的属性访问问题TileSprite以 RenderTexture 或 GLTexture 作为帧源时会抛出控制台警告issue #4719。插件生态更新Spine 与 Facebook Instant Games更新日志同时记录了两个官方插件的更新注意Spine 与 FB Instant Games 插件源码不包含在当前仓库src/plugins中以下内容以更新日志为准Spine Plugin运行时升级至 3.8。Spine 运行时不向后兼容——使用 3.7 及更早版本导出的动画需用 3.8 重新导出。修复了插件绑定导致的场景切换后 Spine 对象空白#4716、纹理图集缓存导致的着色器错误、Container 中多 Spine 对象运行时错误#4710、Loader.setPath多目录加载报错、同名内部图片仅首个文件可加载等问题。Spine 游戏对象不再把默认皮肤名设为default#4764。Facebook Instant Games PluginshowAd/showVideoAd会跳过已展示过的广告同一 Placement ID 无需重复预加载#4728新增内部方法gameStartedHandler解决无资源加载时调用gameStarted抛INVALID_OPERATION的问题#4550修复Leaderboard.getConnectedScores文档参数错误#4702及Leaderboard缺失 Event Emitter 继承的 TypeScript 定义#4703。版本总结与迁移提示Phaser 3.20.0 Fitoria 的核心价值可以浓缩为三点视频成为一等公民从加载VideoFile、缓存Cache.video、设备探测Device.Video、WebGL 纹理createVideoTexture等到游戏对象本体Video形成完整闭环且不预加载、不实时流均可工作物理步长语义纠正Arcade Physics 通过prevFrame、stepsLastFrame归零与移除blocked检查在低帧率下保持稳定同时明确了 delta 方法步级而非帧级的语义API 语义清理Device.Video属性重命名属于破坏性变更升级到 3.20 时若代码中引用了旧命名如device.video.mp4Video需要同步改为新命名device.video.mp4UpdateList._list等私有属性的移除也值得关注。后续版本3.60、4.x在视频能力上继续演进例如基于 Request Video Frame API 的帧回调、VIDEO_METADATA事件、MediaStream 支持loadMediaStream等这些在当前仓库的 Video.js 中均有体现可作为进一步深入阅读的起点。若需在实际项目中验证本文内容建议结合仓库内的 VideoFile 测试、Video 渲染测试 与 配置解析源码 对照阅读。【免费下载链接】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),仅供参考

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价