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

如何从Phaser场景的game实例访问自定义Settings类全局变量?

解决Phaser场景中无法访问全局Settings实例的问题

问题原因

你在main.js里声明的mysettings是ES模块的局部变量,并非真正的全局变量。ES模块拥有独立作用域,其他场景模块(比如MainMenu)无法直接访问另一个模块内的局部变量,因此会抛出mysettings is not defined错误。

可行解决方案

方案1:挂载到Phaser.Game实例上(推荐,符合Phaser生态)

在main.js初始化游戏后,将Settings实例绑定到game对象上:

// main.js
import Settings from './Settings.js';
const mysettings = new Settings();
mysettings.LoadSettings(); // 加载本地存储的设置

import Phaser from 'phaser';
const config = { /* 你的游戏配置 */ };
const game = new Phaser.Game(config);

// 将Settings实例挂载到game对象
game.mysettings = mysettings;

后续在任意场景中,通过this.game.mysettings访问:

// MainMenu场景的create方法
create() {
    const currentSkin = this.game.mysettings._skin;
    // 后续逻辑...
}

方案2:将Settings改成单例模式(更优雅的封装)

修改Settings类,确保全局仅存在一个实例,任何模块导入后都能获取同一个对象:

// Settings.js
export default class Settings {
    static instance;

    constructor() {
        // 单例逻辑:若已有实例,直接返回
        if (Settings.instance) {
            return Settings.instance;
        }
        Settings.instance = this;

        this._gamename = "my_game_";
        this._skin = 1; // 默认蓝色
        this._sound = false;
        this._levels = [];
    }

    LoadSettings() {
        const clr = window.localStorage.getItem(this._gamename + "skin");
        const snd = window.localStorage.getItem(this._gamename + "sound");
        const lvl = window.localStorage.getItem(this._gamename + "levels");

        // 增加默认值,避免localStorage无数据时出错
        this._skin = clr ? parseInt(clr) : 1;
        this._sound = snd === "true"; // localStorage存字符串,直接判断更准确
        this._levels = lvl ? JSON.parse(lvl) : [];
    }

    SaveSettings() {
        window.localStorage.setItem(this._gamename + "skin", this._skin);
        window.localStorage.setItem(this._gamename + "sound", this._sound);
        window.localStorage.setItem(this._gamename + "levels", JSON.stringify(this._levels));
    }

    // 推荐添加getter/setter,避免直接访问私有属性
    get skin() {
        return this._skin;
    }

    set skin(value) {
        this._skin = value;
        this.SaveSettings(); // 修改后自动保存
    }

    get sound() {
        return this._sound;
    }

    set sound(value) {
        this._sound = value;
        this.SaveSettings();
    }

    get levels() {
        return [...this._levels]; // 返回副本,防止外部直接修改数组
    }

    addCompletedLevel(levelId) {
        if (!this._levels.includes(levelId)) {
            this._levels.push(levelId);
            this.SaveSettings();
        }
    }
}

使用方式:

// main.js
import Settings from './Settings.js';
const mysettings = new Settings();
mysettings.LoadSettings();

// 任意场景(比如MainMenu.js)
import Settings from './Settings.js';
const mysettings = new Settings(); // 自动获取全局唯一实例

create() {
    const currentSkin = mysettings.skin; // 使用getter访问
    // 修改设置时用setter,自动保存
    mysettings.sound = true;
}

方案3:挂载到window对象(简单但不推荐)

直接将Settings实例挂到浏览器全局window对象上,任何地方都能直接访问:

// main.js
import Settings from './Settings.js';
window.mysettings = new Settings();
window.mysettings.LoadSettings();

场景内直接使用:

// MainMenu场景的create方法
create() {
    const currentSkin = mysettings._skin;
}

⚠️ 缺点:污染全局作用域,大型项目易出现变量冲突,不建议在复杂项目中使用。

额外优化建议

  • 为Settings类添加错误处理,比如JSON.parse(lvl)时捕获异常,避免localStorage数据损坏导致游戏崩溃。
  • 用getter/setter封装属性,禁止外部直接修改私有变量(如_skin),保证数据一致性。
  • 初始化时优先调用LoadSettings(),确保加载本地存储的最新设置,而非默认值。

内容的提问来源于stack exchange,提问作者BdR

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 07:15:17