如何根据内容调整Phaser 3项目中模态框的高度?
问题:Phaser 3 模态框根据内容动态调整高度
我正在为Phaser 3项目创建模态框场景,当前modal.js代码如下:
class modal extends Phaser.Scene { // constructor constructor() { super("Modal"); } preload() { this.load.image("header", "Assets/popUpTop.png"); this.load.image("x", "Assets/x.png"); } init(data) { this.modalName = data.modalName; } create() { // create a white rounded rectangle as modal background var bgGrafics = this.make.graphics(); bgGrafics.fillStyle(0xffffff, 1); bgGrafics.fillRoundedRect(0, 0, gameConfig.width / 3, gameConfig.height / 1.7, 51); bgGrafics.generateTexture("modalBg", gameConfig.width / 3, gameConfig.height / 1.7); this.modalBg = this.add.sprite(gameConfig.width / 2, gameConfig.height / 2, "modalBg"); this.modalBg.setScale(1.05); this.headerBg = this.add.image(0, 0, "header"); this.headerBg.setScale((this.modalBg.width * 1.05 / this.headerBg.width), (1 + (0.05 * this.modalBg.height / this.headerBg.height))); this.closeBtn = new RoundedButton(this, 0, 0, 43, "x", 1.3, () => {this.close()}); // RoundedButton is a custom class that extends Phaser.GameObjects.Container this.add.existing(this.closeBtn); // help modal if(this.modalName === 'help') { // add content of help modal } // profile modal else if(this.modalName === 'profile') { // add content of profile modal } // confirm spin modal else if(this.modalName === 'spin') { // add content of confirm modal } Phaser.Display.Align.In.TopRight(this.closeBtn, this.modalBg); Phaser.Display.Align.In.TopCenter( this.headerBg, this.modalBg ); } close() { this.scene.stop('Modal'); this.scene.run('PlayGame'); } }
如代码所示,我尝试根据modalName为模态框添加不同内容,但无法找到根据内容调整模态框高度的方法,该如何实现?
解决方案
方法1:预设不同模态框的高度配置
适合内容固定、高度可提前预估的场景,直接为每个模态框定义对应的高度参数:
// 在类外部或内部定义模态框配置 const modalConfigs = { help: { height: gameConfig.height / 1.5 }, // 帮助内容较多,高度稍大 profile: { height: gameConfig.height / 2 }, // 个人信息内容适中 spin: { height: gameConfig.height / 3 } // 确认弹窗内容少,高度较小 }; class modal extends Phaser.Scene { // ... 其他代码不变 create() { // 获取当前模态框的配置,默认使用原固定高度 const config = modalConfigs[this.modalName] || { height: gameConfig.height / 1.7 }; // 动态生成适配高度的背景 var bgGrafics = this.make.graphics(); bgGrafics.fillStyle(0xffffff, 1); bgGrafics.fillRoundedRect(0, 0, gameConfig.width / 3, config.height, 51); bgGrafics.generateTexture("modalBg", gameConfig.width / 3, config.height); this.modalBg = this.add.sprite(gameConfig.width / 2, gameConfig.height / 2, "modalBg"); this.modalBg.setScale(1.05); // 调整headerBg缩放以适配新的背景高度 this.headerBg = this.add.image(0, 0, "header"); this.headerBg.setScale( (this.modalBg.width * 1.05 / this.headerBg.width), (1 + (0.05 * this.modalBg.height / this.headerBg.height)) ); this.closeBtn = new RoundedButton(this, 0, 0, 43, "x", 1.3, () => {this.close()}); this.add.existing(this.closeBtn); // 添加对应模态框内容 if(this.modalName === 'help') { const helpText = this.add.text(0, 0, "这是帮助内容,包含游戏玩法、规则说明...", { fontSize: '16px', color: '#333', wordWrap: { width: gameConfig.width / 3 - 40 } }); Phaser.Display.Align.In.Center(helpText, this.modalBg); } else if(this.modalName === 'profile') { const avatar = this.add.image(0, 0, 'avatar'); Phaser.Display.Align.In.TopCenter(avatar, this.modalBg, 0, 50); const userName = this.add.text(0, 0, "玩家昵称", { fontSize: '18px', color: '#000' }); Phaser.Display.Align.In.Center(userName, this.modalBg); } else if(this.modalName === 'spin') { const confirmText = this.add.text(0, 0, "确认消耗金币进行旋转吗?", { fontSize: '16px', color: '#333' }); Phaser.Display.Align.In.Center(confirmText, this.modalBg); const confirmBtn = new RoundedButton(this, 0, 0, 60, "确认", 1, () => { /* 执行旋转逻辑 */ }); this.add.existing(confirmBtn); Phaser.Display.Align.In.BottomCenter(confirmBtn, this.modalBg, 0, 30); } Phaser.Display.Align.In.TopRight(this.closeBtn, this.modalBg); Phaser.Display.Align.In.TopCenter( this.headerBg, this.modalBg ); } // ... 其他代码不变 }
方法2:自动计算内容高度(更灵活)
适合内容长度不确定的场景,通过容器包裹内容后,动态计算实际高度来生成背景:
class modal extends Phaser.Scene { // ... 其他代码不变 create() { const modalWidth = gameConfig.width / 3; // 创建内容容器,用于统一管理模态框内的所有元素 const contentContainer = this.add.container(gameConfig.width / 2, gameConfig.height / 2); // 根据模态框类型添加内容到容器 if(this.modalName === 'help') { const helpText = this.add.text(0, 0, "这是帮助内容,可能包含多行文本,长度不固定...", { fontSize: '16px', color: '#333', wordWrap: { width: modalWidth - 40 } }); contentContainer.add(helpText); // 为内容添加上下边距 helpText.setPosition(0, 0); } else if(this.modalName === 'profile') { const avatar = this.add.image(0, -50, 'avatar'); const userName = this.add.text(0, 20, "玩家昵称", { fontSize: '18px', color: '#000' }); const levelText = this.add.text(0, 50, "等级:10", { fontSize: '14px', color: '#666' }); contentContainer.add([avatar, userName, levelText]); } else if(this.modalName === 'spin') { const confirmText = this.add.text(0, 0, "确认消耗金币进行旋转吗?", { fontSize: '16px', color: '#333' }); const confirmBtn = new RoundedButton(this, 0, 40, 60, "确认", 1, () => { /* 执行旋转逻辑 */ }); contentContainer.add([confirmText, confirmBtn]); } // 获取内容容器的实际高度,加上上下边距 const contentBounds = contentContainer.getBounds(); const modalHeight = contentBounds.height + 80; // 80为上下边距 // 生成适配高度的背景 var bgGrafics = this.make.graphics(); bgGrafics.fillStyle(0xffffff, 1); bgGrafics.fillRoundedRect(0, 0, modalWidth, modalHeight, 51); bgGrafics.generateTexture("modalBg", modalWidth, modalHeight); this.modalBg = this.add.sprite(gameConfig.width / 2, gameConfig.height / 2, "modalBg"); this.modalBg.setScale(1.05); // 调整header和关闭按钮 this.headerBg = this.add.image(0, 0, "header"); this.headerBg.setScale( (this.modalBg.width * 1.05 / this.headerBg.width), (1 + (0.05 * this.modalBg.height / this.headerBg.height)) ); this.closeBtn = new RoundedButton(this, 0, 0, 43, "x", 1.3, () => {this.close()}); this.add.existing(this.closeBtn); // 确保内容在背景之上 contentContainer.setDepth(this.modalBg.depth + 1); Phaser.Display.Align.In.TopRight(this.closeBtn, this.modalBg); Phaser.Display.Align.In.TopCenter( this.headerBg, this.modalBg ); } // ... 其他代码不变 }
内容的提问来源于stack exchange,提问作者Faezeh Keshmiri
相关产品推荐
相关产品推荐

