How to unambiguously identify game object in a scene?

I’m trying to add interactive image objects on a scene from an array of objects I’m getting from JSON.

For example, I have this JSON:

{
  "graph": {
    "nodes": [
      {"name":"Catharsis", "type":"city",    "x":500, "y":200},
      {"name":"Arrakeen",  "type":"city",    "x":300, "y":400},
      {"name":"Mine_1",    "type":"facility","x":150, "y":450},
      {"name":"Belgorod",  "type":"city",    "x":700, "y":500}
    ],
    "paths": [
      {"from":"Arrakeen", "to":"Belgorod"},
      {"from":"Arrakeen", "to":"Mine_1"},
      {"from":"Arrakeen", "to":"Catharsis"}
    ]
  }
}

Nodes are locations, like cities and facilities.
This JSON is loaded as JS object into mapData

Then this JS draws objects in scene:

preload(){
  this.load.image('city','img/locations/city.png');
  this.load.image('facility','img/locations/facility.png');
}

create(){
  mapData.graph.paths.forEach(path => {
    var nodesFrom = mapData.graph.nodes
      .find(node => {
        return node.name == path.from
      }, path);
    var nodesTo = mapData.graph.nodes
      .find(node => {
        return node.name == path.to
      }, path);
    this.add.line(0, 0, nodesFrom.x, nodesFrom.y, nodesTo.x, nodesTo.y, 0x000000, 1)
      .setOrigin(0, 0);
  }, this);
  mapData.graph.nodes.forEach(node => {
    this.add.image(node.x,node.y,node.type)
      .setInteractive()
      .setScale(0.2);
    this.add.text(node.x,node.y,node.name,{fontSize:20,color:'#000'})
      .setOrigin(0.5, 0.3);
    this.input.on('gameobjectdown',this.onObjectClicked);
  }, this);
}

And this is the resulting scene:

But I want to show context menu of actions when one of the cities or facilities is clicked. With the list of menu items formed conditionally. For example, Move to [city.name] etc. But now all of the interactive objects send click events when one is clicked, so I need to somehow identify added images unambigously. Maybe add a key equal to the name of node, but how? And how to read it afterwards?

Hello,
Nice job structuring your data and code. There is one thing I noticed when reviewing your create function and that’s that, this.input.on('gameobjectdown',this.onObjectClicked); is placed within a forEach loop. You only need to add that listener once, so it would be best to move it outside of the loop.

As far as figuring out which city is clicked on, your this.onObjectClicked method should look like the following:

onObjectClicked(pointer, object)
{
    let objectName = object.texture.key;
    if(objectName === "cityName") //Do a thing.
}
1 Like

You can use GameObject#name.

1 Like

Can you give an example of how to use it? Just pass it as an object into add function like this?
this.add.image(/*other arguments*/ {name: node.name})
and then call it like this: gameObject.name

Update: Well, this particular syntax seems to be non-working.

this.add.image(node.x, node.y, node.type)
  .setName(node.name)
  // etc.
3 Likes