Search code examples
javascripttypescriptphaser-framework

How to access a custom class Settings global variable from Phaser.scene `game` instance?


I want to create a Settings global variable, which contains all the game setting and I can use in the different scenes. I want to access the settings in my LevelSelect-scene, to display which levels have been unlocked. And I also want to access it in the Game-scene, to determine which player color to use. And in a separate Settings-scene to let the player select a skin and set the sound on/off

So, I created a class Settings that neatly contains all the loading, saving and accessing the settings, see code below (btw It's not complete, it also needs extra error handling and other settings, but that's exactly why I want to put that code in a separate custom object)

// Settings object
export default class Settings
{
    constructor ()
    {
        // game name
        this._gamename = "my_game_"
        // settings
        this._skin = 1; // blue
        this._sound = false;
        this._levels = []; // completed levels
    }

    LoadSettings()
    {
        // load from localstorage
        var clr = window.localStorage.getItem(this._gamename + "skin");
        var snd = window.localStorage.getItem(this._gamename + "sound");
        var lvl = window.localStorage.getItem(this._gamename + "levels");

        // settings variables
        this._skin = parseInt(clr);
        this._sound = (snd ? true : false);
        this._levels = JSON.parse(lvl);
    }

    SaveSettings()
    {
        // save to localstorage
        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));
    }
}

I instantiate ths Settings class in the main.js together where also the let game = Phaser is declared, so it looks like this:

import Settings from './Settings.js';
var mysettings = new Settings();

import Phaser from 'phaser';
//.. etc.
let game = new Phaser.Game(config);

However, the problem is that when I try to access the mysettings global variable from the MainMenu-scene (or any scene) I get an error "mysettings is not defined"

export default class MainMenu extends Phaser.Scene
{
    constructor () { super('MainMenu'); }

    create () {
      var clr = mysettings._skin;
      // ** ReferenceError: mysettings is not defined

The mysettings is declared as a global variable afaik, so shouldn't it be accessible in the game instance? What am I doing wrong here? Or, how can I create such a global variable that can easily be accessed in all scenes?


Solution

  • This is not the reason why the error happens, but if you are using a global variable, a maybe nicer solution would to create the "global" variable in the settings file, and you just have to import the settings file in any file that wants to use it, and it should work (and the code is a bit easier to read/traverse).

    // in: settings.ts
    // the export of the class is optional
    export class Settings {
        constructor(){
           // ...
        }
        // ...
    }
    
    export const CURRENT_SETTINGS = new Settings();
    

    in other files you just call

     // in main.ts (for example)
     import  { CURRENT_SETTINGS } from "./settings";
     // ...
    
     console.info( CURRENT_SETTINGS.someCoolProperty ); 
    

    (And no special compiler options/infos/... are needed to tell the compile, what that global variable is and of which type)