-1

In my game, I've created a list of gameObjects (instances of other classes such as Player) in my Main that I can loop through and render in one function, rather than rendering them all individually. This is my render function;

this.gameObjects = [];

addObj(obj){
  this.gameObjects.push(obj);
}

render(){
  this.gameObjects.forEach(obj => obj.render());
}

This works no problem if I want to add another gameObject using my main class like this;

let main = new Main();
let player = new Player(10, 30, 10, 10, 'red');

main.addObject(player);
main.start();

However, I want to add another gameObject, called Projectile within my Player class. The problem is my Player class doesn't have access to Main's addObj function.

My idea was to create a singleton, that holds a list of game objects, like this;

class Repository{
  constructor(){
    if(this.instance){
      return this.instance;
    }
    
    this.list = [];
    this.instance = this;
  }
  
  get obj(){...}
  addObj(obj){...}
}

The tl:dr of the question is;

  • Is this the best way to go forward?
  • How would I access this singleton? By importing it everywhere I needed it?
  • Create a global variable with an instance? How would I do this?
  • Am I over thinking this? Should I just pass main in to each class and access its methods that way?
Lewis
  • 3,479
  • 25
  • 40

1 Answers1

1

Using a singleton might complicate unit tests, and add a hidden state to the information flow of the application. It's not that the pattern is inherently flawed, but there's a right and wrong way to use this pattern, and if you don't intend to spend the time and understand the pattern, you're probably better off not using it. Your plan for the Singleton will work, it's just not the most robust solution.

Notice that JS is a functional language. You don't need to pass main to each class, you can just pass the addObject function. That way when you change context (for example in unit tests or if you'll recycle the code for other projects) you'll be able to just switched the passed function, and keep all of your code.

nihohit
  • 498
  • 3
  • 23
  • Thanks for the information - that makes a lot of sense. It's a little cumbersome having to pass that method to each class where I want to use it just so I can have a single set of objects. I can see it getting messy if I want this in more than just a couple of places but I guess visibility/clarity are definitely more important. – Lewis Jul 18 '19 at 12:33
  • So I tried passing the `addObject()` function through to player, but when I use it it seems that the context of `this` is lost within the function. Any ideas? (To be specific, it complains of trying to push to an undefined array - but it works when called from main) – Lewis Jul 18 '19 at 13:05
  • 1
    It's because 'this' is bound to the calling object. You'll need to capture 'this' as a variable, and use the variable in the function. https://stackoverflow.com/questions/34930771/why-is-this-undefined-inside-class-method-when-using-promises/34930859 – nihohit Jul 19 '19 at 07:44