You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Phaser 3 相机缩小时如何锁定UI文本位置并修复tileSprite背景异常

问题描述

我正在开发一款刀剑类游戏,核心玩法为收集硬币使角色变大后与其他玩家对战,目前已实现效果如下:
Player gets bigger as he collects coins
可以看到玩家收集硬币后体积会持续增长,一段时间后角色体积会占满整个屏幕。
big player
因此我需要根据玩家体积动态调整相机Zoom out的比例。我在create函数中的初始相机配置如下:
this.cameras.main.startFollow(this.mePlayer);
我在该行前添加了缩放代码:
this.cameras.main.setZoom(0.5)
调整后出现两个问题:所有UI文本都变小,同时tileSprite背景也出现显示异常。
enter image description here
我的文本创建代码如下:

//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,两者互不干扰即可解决问题。

具体实现步骤

  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));
  1. 修复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;
  1. 修复背景显示异常
    背景交给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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.29 12:06:01