0

I'm currently working on a game, using HTML5 and Javascript. Right now, I'm adding sound, and also want the classic 'turn music on/off' and 'turn sounds on/off' buttons. I don't want to have to keep track of all of my Audio objects, and loop over them each time I set one of these buttons, so I've declared two global booleans, music and sound, both defaulting to true. When they're true, their respective Audio objects play, and when false, they don't.

This is easy enough to do on object creation, with a simple if statement. However, if I want to change the state of the object after creation, if the user changes either setting, then it becomes an inconvenience. I'd like to be able to put a callback on the booleans, saying effectively: (pseudocode)

var music = true;

class Music() {
    this.audio = new Audio(fileName);

    music.onUpdate(function() {
        if(music) {
            this.audio.play();
        } else {
            this.audio.pause();
        }
    }

    if(music) {
        this.audio.play();
    }
}

Furthermore, it would be even better if I could cascade these, so that several callbacks could be registered to the same variable. I appreciate that this is not something that would need to be done regularly, however is there a simple language feature I could use to implement this, before I completely rewrite this bit of the project?

Thanks

CWood
  • 13
  • 4

1 Answers1

0

You can wrap the variable in an object that implements a simple event handling mechanism, here's an example:

var variable = {
  _value: true,
  set: function(value) {
    if (value !== this._value) {
      this._value = value;
      for (var i = 0; i < this._callbacks.length; i++) {
        this._callbacks[i](value);
      }
    }
  },
  get: function() { return this._value; },

  _callbacks: [],
  onChange: function(callback) {
    this._callbacks.push(callback);
  },
  offChange: function(callback) {
    // Find the callback and remove it from the _callbacks array.
    // If !callback, this._callbacks = [];
  }
}

// Usage:
variable.onChange(function(value) { console.log(value); });

variable.set(false); // 'false' logged to the console
variable.set(false); // nothing is logged to the console

You can add multiple listeners with the onChange method. All of them will be called when the value changes. You can remove event listeners with the offChange method. I added it for completeness.

You can get this out-of-the-box by using a library supporting Observable Objects. There are many available if you look around but also include many more features that you might not need.

simich
  • 358
  • 2
  • 10