lundi 30 janvier 2017

How to properly pass data in Object Observer Pattern?

I'm working on refactoring my functional game into classical structure. I know JavaScript doesn't have explicit classes, I'm using the inverse prototype structure to create classes (typical in JS these days). I'm also using Require as the means for modularity. My game is built on the Famous JavaScript engine (v0.6 before they abandoned development) which uses the Object Observer pattern.

My main problem is that I can't conceptualize how to properly pass data between my different classes and their update functions.

Here is an example - Inside a class I've called Game which is my game view, I create my character object, a Node in the FamousEngine Scene. I attach to it a visual element DOMElement and I give it all my desired properties. I then create a new object, my custom component that will be the Observer. This component has 3 functions, onMount, onReceive, onUpdate. onMount handles the logic of attaching this component to a Node. onReceive handles the logic of receiving an event emitted by FamousEngine. onUpdate handles the logic of what should happen once the Engine has queued up and is ready to execute this component's update.

Code -

var boxNode = this.UI.gameUI.addChild();
boxNode.ratio = 0.8;
boxNode.setSizeMode('absolute', 'absolute').setAbsoluteSize(80 * boxNode.ratio, 120 * boxNode.ratio).setAlign(0.5, 0.5).setPosition(-36 * boxNode.ratio, -60 * boxNode.ratio, 10000).setOrigin(0.5, 0.5);
boxNode.size = { w: 80, h: 120 };
boxNode.DOMElement = new DOMElement(boxNode);
boxNode.DOMElement.setProperty('background-image', 'url(./images/astro_loop.png)').setProperty('background-size', '800% 300%').setProperty('z-index', '1000');

var boxNodeComponentID = boxNode.addComponent({
  id: null,
  node: null,
  onMount: function onMount(node) {
    this.id = node.addComponent(this);
    this.node = node;
  },
  onReceive: function onReceive(event, payload) {
    if (event == 'resetAstro') game.boxNode.setAlign(0.5, 0.7).setPosition(-20, -20, 1000);
  },
  onUpdate: function onUpdate(time) {
    if (this.game.started == true && game.boxSet != true) {
      boxNode.setAlign(0, 0);
      boxNode.box.setPosition(gameSize[0] / 2, gameSize[1] / 2, 0);
      game.boxSet = true;
    }
    var boxPosition = boxNode.box.getPosition();
    boxNode.setPosition(boxPosition.x - 10, boxPosition.y - 20, 10000);
    boxNode.requestUpdate(this.id);
  }
});
boxNode.requestUpdate(boxNodeComponentID);

Now my problem is that I can't seem to figure out how to properly reference anything inside my onUpdate. this.game.started throws a reference error because this references the current component. The way I'm working with with this currently is actually that this component references the node it's attached to this.node which references the FamousEngine in its whole under the private member _updater. So what I've done is attached my character to it's class Game and attached Game to FamousEngine. I get these long ugly references calls inside my onUpdate methods in order to change anything - this.node._updater.Game.BoxNode. this.node._updater

How can I pass my character object, and hopefully many others, properly to these update functions? I feel like these kind of references to private members are not good or proper. It gets more complicated than above when I try to reference an update from a different class. Basically in my example I can reference boxNode since it is declared above the component creation function, but if I pull in a class via require, I no longer have that reference.

I'm sorry if my issue is not clear, I will do what I can to clean up the question.

Aucun commentaire:

Enregistrer un commentaire