0
\$\begingroup\$

OK, so I'm creating a <canvas> game using JavaScript (ES6+) features like Classes. It's straight from the vue-cli and webpack.

So, I have these Classes with the following (and such) variables

class Player {
    this.x = 1;
    this.y = 5;
    this.name = 'Guy';
    this.stats = [];
}

class Map {
    this.level = 1;
    this.config = {};
    this.images = Image();
    this.canvas = null;
    this.context = null;
    this.board = []; // From a tileset
}

// POINT OF ENTRY STARTS HERE
// const game = new Game();
class Game {
    this.map = null;
    this.player = null;
    this.assets = Images(); 
}

The problem I'm having is that sometimes, I'm having to access a created object that was instantiated elsewhere.

For example, this.player was instantiated inside the Game class. But in the Map class, I have the drawMouseSelection method where it needs the current Player's X and Y and Map's board array of tiles.

For example, I pass the all of board[2500] to a static helper method in UI class to get the correct tile hovered on.

** What I am doing**

I just pass the whole object and deal with it as such. Am I passing too big of objects?

\$\endgroup\$
2
\$\begingroup\$

In JavaScript, objects are references (and arrays are objects, so they are also references). So when you pass a huge object to a function, you don't create a copy of said object. The function operates on the original object. So passing objects to functions won't become a performance bottleneck, no matter how much data these objects include. So when map.drawMouseSelection needs the current player, then there is nothing wrong with passing the whole player-object to it.

If you have many more functions in map which require the current player, you can just pass the player to the map when you instantiate it and store it in a local variable. Or you can even go a step further and give map a reference to the game which instantiated it, so it can obtain the current player through it when needed.

But there are other ways to handle object dependencies in JavaScript.

The first thing you need to understand about JavaScript classes is that JavaScript actually has no classes. The new class keyword is a lie. JavaScript's object orientation is still prototype-based, not class-based. A class is just syntactic sugar for how JavaScript always worked. They are just regular object-constructor functions in global scope, and functions are yet another type of object. So when you only have one Player, one Game and one Map at once in your game, and the "classes" for them are objects in global scope anyway, there is nothing wrong with replacing them with literal global objects.

Another way to do this is to expose data with Getter-functions. For example, if the UI wants to know which tile is below the mouse cursor, it should call a function like game.map.getTileAt(x, y). The map then returns the tile at those coordinates. The UI class doesn't need to know how the Map class accomplishes that. So if you later decide to replace the one-dimensional board with a 2d array, a spatial hashtable or an auto-balanced quadtree, the UI class doesn't need to be changed.

\$\endgroup\$
  • \$\begingroup\$ I think I see what you're saying. If you have many more functions in map which require the current player, you can just pass the player to the map when you instantiate it and store it in a local variable. Or you can even go a step further and give map a reference to the game which instantiated it, so it can obtain the current player through it when needed. By doing this, I can pass the new Player() to the map.js class and place in the __constructor like this.player and go from there. Where in player.js, I can do this.x and map.js, I do this.player.x. \$\endgroup\$ – Dan Dec 30 '17 at 21:59
  • \$\begingroup\$ But then I figured, well, I don't want to keep passing whole objects to even smaller objects, to for example like utility methods. So, when you said about "exposing data with getter-functions".. Could you go on a bit more about this or what exactly is this called? Thank you. \$\endgroup\$ – Dan Dec 30 '17 at 22:03
  • \$\begingroup\$ @DanJasnowski First comment: Yes, that's about it. Second comment: A getter-function is a public function which returns the value of a private variable. \$\endgroup\$ – Philipp Dec 31 '17 at 2:36

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.