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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 18:54:24