Phaser 3跨场景共享单例Inventory对象实现方案咨询
Phaser 3 场景间共享 Inventory 对象的可行方案
先提下你代码里的几个小问题,避免后续出bug:
- 类里定义的是
this.stuff,但所有方法里用的是this.items,变量名不统一 collcet拼写错误,应该是collect- 赋值用了
==(比较运算符),应该改成=(赋值运算符)
你不需要重新设计,Phaser 3 有几种成熟的方式实现场景间数据共享,以下是具体方案:
方案一:利用全局游戏对象存储实例
Phaser 的this.game对象在所有场景中都能访问,你可以把 Inventory 实例挂载到这里,实现全局访问:
第一步:修正并抽离 Inventory 类
建议把 Inventory 和 Player GameObject 解耦,让职责更清晰:
class Inventory { constructor() { // 初始化10格背包 this.items = [null, null, null, null, null, null, null, null, null, null]; } collect(item) { let space = 0; while (space < 10) { if (this.items[space] === null) { this.items[space] = item; break; } space++; } } has(item) { let space = 0; while (space < 10) { if (this.items[space] === item) { return true; } space++; } return false; } takeOut(item) { let space = 0; while (space < 10) { if (this.items[space] === item) { this.items[space] = null; break; } space++; } } }
第二步:在启动场景挂载实例
比如在 Boot 场景(游戏第一个加载的场景)里初始化并挂载:
class BootScene extends Phaser.Scene { constructor() { super('BootScene'); } create() { // 创建唯一的Inventory实例,挂载到全局game对象 this.game.inventory = new Inventory(); // 切换到第一个游戏场景 this.scene.start('GameScene1'); } }
第三步:任意场景中访问
之后在任何场景里,直接通过this.game.inventory操作背包:
// 收集物品 this.game.inventory.collect('apple'); // 检查是否拥有物品 if (this.game.inventory.has('apple')) { console.log('背包里有苹果'); } // 取出物品 this.game.inventory.takeOut('apple');
方案二:实现单例模式的 Inventory 类
把 Inventory 设计成单例,确保全局只有一个实例,任何场景调用都能拿到同一个对象:
class Inventory { static instance; constructor() { // 如果已经有实例,直接返回现有实例 if (Inventory.instance) { return Inventory.instance; } this.items = [null, null, null, null, null, null, null, null, null, null]; Inventory.instance = this; } collect(item) { let space = 0; while (space < 10) { if (this.items[space] === null) { this.items[space] = item; break; } space++; } } has(item) { let space = 0; while (space < 10) { if (this.items[space] === item) { return true; } space++; } return false; } takeOut(item) { let space = 0; while (space < 10) { if (this.items[space] === item) { this.items[space] = null; break; } space++; } } }
使用方式
不管在哪个场景调用new Inventory(),都会拿到同一个实例:
// 场景1中初始化并操作 const inventory = new Inventory(); inventory.collect('apple'); // 场景2中直接调用,拿到的是同一个背包 const sameInventory = new Inventory(); console.log(sameInventory.has('apple')); // 输出true
方案三:场景切换时传递参数(适合临时数据)
如果只是场景切换时临时传递数据,可以在切换时携带参数:
// 从场景A切换到场景B时,传递inventory实例 this.scene.start('SceneB', { inventory: this.inventory });
然后在场景B的init方法中接收:
class SceneB extends Phaser.Scene { constructor() { super('SceneB'); } init(data) { // 接收传递的inventory this.inventory = data.inventory; } create() { // 直接操作背包 this.inventory.collect('sword'); } }
这种方式需要每次切换场景手动传递,适合临时数据,不适合全局持久的背包系统。
内容的提问来源于stack exchange,提问作者EmptyStone
相关产品推荐
相关产品推荐

