如何从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
相关产品推荐
相关产品推荐

