Phaser 3 相机缩小时如何锁定UI文本位置并修复tileSprite背景异常
问题描述
我正在开发一款刀剑类游戏,核心玩法为收集硬币使角色变大后与其他玩家对战,目前已实现效果如下:
可以看到玩家收集硬币后体积会持续增长,一段时间后角色体积会占满整个屏幕。
因此我需要根据玩家体积动态调整相机Zoom out的比例。我在create函数中的初始相机配置如下:this.cameras.main.startFollow(this.mePlayer);
我在该行前添加了缩放代码:this.cameras.main.setZoom(0.5)
调整后出现两个问题:所有UI文本都变小,同时tileSprite背景也出现显示异常。
我的文本创建代码如下:
//killcounter this.killCount = this.add.text(window.innerWidth / 1.5, 0, 'Kills: 0', { fontFamily: 'Georgia, "Goudy Bookletter 1911", Times, serif' }).setFontSize(40).setDepth(101); this.killCount.scrollFactorX = 0 this.killCount.scrollFactorY = 0 //player+fpscounter this.playerCount = this.add.text(this.cameras.main.worldView.x*this.cameras.main.zoom, this.cameras.main.worldView.y*this.cameras.main.zoom, 'Players: 0' + "\nFPS: 0", { fontFamily: 'Georgia, "Goudy Bookletter 1911", Times, serif' }).setFontSize(20).setDepth(101); this.playerCount.scrollFactorX = 0 this.playerCount.scrollFactorY = 0
相机配置代码如下:
this.cameras.main.startFollow(this.mePlayer);
背景相关代码如下:
//in create function this.background = this.add.tileSprite(0, 0, window.innerWidth, window.innerHeight, 'background').setOrigin(0).setScrollFactor(0, 0); this.background.fixedToCamera = true; //in update function this.background.setTilePosition(this.cameras.main.scrollX, this.cameras.main.scrollY);
请问是否有方案可以在相机缩小时,让UI文本保持固定位置和原始大小,同时修复背景显示异常?
解决方案
核心原理
Phaser支持多相机分层渲染,把游戏世界内容(玩家、硬币、对战单位)和UI/固定背景拆分给两个独立相机渲染,主相机负责跟随玩家、动态调整缩放,UI相机固定缩放为1,两者互不干扰即可解决问题。
具体实现步骤
- 配置双相机分层规则(在create函数中完成)
// 主相机保留原有逻辑,仅负责游戏世界内容渲染,后续动态缩放只修改主相机zoom this.cameras.main.startFollow(this.mePlayer); // 新建UI相机,位置和尺寸和画布保持一致,固定缩放为1 this.uiCamera = this.cameras.add(0, 0, window.innerWidth, window.innerHeight); this.uiCamera.setZoom(1); // 配置相机渲染过滤:主相机不渲染UI和背景,UI相机不渲染游戏内容 // 约定游戏内交互元素depth小于100,UI、背景元素depth大于等于100 this.cameras.main.ignore([this.background, this.killCount, this.playerCount]); this.uiCamera.ignore(this.children.list.filter(child => child.depth < 100));
- 修复UI文本显示
UI元素交给固定缩放的UI相机后,不需要再适配主相机缩放值,直接用屏幕像素坐标即可,自动保持原始大小和固定位置:
// 文本坐标可以直接简化为屏幕相对坐标,无需乘zoom参数 this.playerCount = this.add.text(10, 10, 'Players: 0' + "\nFPS: 0", { fontFamily: 'Georgia, "Goudy Bookletter 1911", Times, serif' }).setFontSize(20).setDepth(101); this.playerCount.scrollFactorX = 0; this.playerCount.scrollFactorY = 0;
- 修复背景显示异常
背景交给UI相机后,不需要再在update函数中同步tilePosition,也不需要用已废弃的fixedToCamera属性,原有代码简化为:
// create函数中背景代码 this.background = this.add.tileSprite(0, 0, window.innerWidth, window.innerHeight, 'background').setOrigin(0).setScrollFactor(0, 0).setDepth(100); // 直接删除update函数中的this.background.setTilePosition(...)代码即可
后续需要根据玩家体积调整视野时,仅修改this.cameras.main.zoom参数即可,完全不会影响UI和背景的显示效果。
内容的提问来源于stack exchange,提问作者Coder Gautam YT
相关产品推荐
相关产品推荐

