Phaser多场景重构后游戏黑屏无法启动求助
问题背景
单场景写法的Phaser游戏原本运行正常,重构为类式多场景结构后出现黑屏,无法正常渲染游戏内容。目标是实现多场景分离,后续通过场景重叠实现游戏UI、菜单、结束界面等功能。
旧单场景代码
let config = { type: Phaser.AUTO, width: 3000, height: 1250, autoCenter: true, backgroundColor: '#1c1c1c', physics: { default: 'arcade', arcade: { gravity: { y: 0 }, debug: true } }, scene: { preload: preload, create: create, update: update } }; const game = new Phaser.Game(config); function preload() {...} function create() {...} function update() {...}
重构后的多场景代码框架
class GameScene extends Phaser.Scene { constructor(config) { super(config); } preload(){...} create(){...} update(){...} } var config = { type: Phaser.AUTO, parent: "phaser-game", width: 3000, height: 1250, autoCenter: true, backgroundColor: '#1c1c1c', physics: { default: 'arcade', arcade: { gravity: { y: 0 }, debug: true } }, }; var game = new Phaser.Game(config); game.scene.add("Game", GameScene); game.scene.start("Game");
问题排查
对比完整代码,定位到几个核心问题:
Scene构造函数参数错误
Phaser的Scene构造函数无需传入config参数,原代码中constructor(config)并传递给super(config)会导致场景初始化逻辑异常。全局变量未声明
preload方法中cursors = this.input.keyboard.createCursorKeys();未使用let/var声明,在严格模式下会抛出错误,中断游戏初始化流程。未定义的
getMap()函数create方法中调用var level = getMap();,但该函数未实现,直接抛出引用错误,导致场景创建失败。重复启用容器物理体
先后执行this.physics.add.existing(this.cPlayer);和this.physics.world.enableBody(this.cPlayer);,重复操作可能引发物理体状态异常。
修复方案
1. 修正Scene构造函数
将构造函数改为Phaser标准写法,无需额外参数:
class GameScene extends Phaser.Scene { constructor() { super('Game'); // 指定场景唯一标识key } // 其他方法保持不变 }
2. 规范变量声明
将cursors挂载到场景实例,避免全局变量污染:
// preload方法内修改 this.keys = this.input.keyboard.addKeys('SPACE,W,A,S,D,Q'); this.cursors = this.input.keyboard.createCursorKeys(); // update方法内对应修改 if (this.cursors.left.isDown || this.keys.A.isDown) { // 玩家移动逻辑 }
3. 实现getMap()函数
补充地图数据生成函数,返回符合tilemap要求的二维数组:
function getMap() { // 示例地图数据,替换为实际游戏地图 return [ [0,0,0,0,0,0], [2,1,1,1,1,3], [2,1,13,1,1,3], [2,1,1,1,1,3], [4,4,4,4,4,4] ]; }
4. 移除重复的物理体启用代码
删除create方法中的this.physics.world.enableBody(this.cPlayer);,仅保留this.physics.add.existing(this.cPlayer);即可完成容器物理体的初始化。
5. 可选:简化场景注册方式
直接在配置中注册场景,无需手动调用add和start:
var config = { type: Phaser.AUTO, parent: "phaser-game", width: 3000, height: 1250, autoCenter: true, backgroundColor: '#1c1c1c', physics: { default: 'arcade', arcade: { gravity: { y: 0 }, debug: true } }, scene: [GameScene] // 直接传入场景类,Phaser自动初始化并启动第一个场景 }; var game = new Phaser.Game(config);
修复后验证
修改完成后,游戏可正常加载场景、渲染地图与玩家。后续可添加UIScene、MenuScene等新场景,通过game.scene.launch("UIScene")实现场景重叠,完成UI与游戏内容的分离。
内容的提问来源于stack exchange,提问作者JackF99

