createFromObjects does not take Tiled object id as argument

The docs for tilemap.createFromObjects() say this:

The gid argument is matched against:

  1. For a tile object, the tile identifier ( gid ); or
  2. The object’s unique ID ( id ); or
  3. The object’s name (a string)

I have a use case where it would be ideal to locate map objects by their id, not by their name or GID. However, when I try to do this:

this.endpoints = this.map.objects.endpoints;

        this.ledgesGroup.endsgroup = this.game.add.group(this.ledgesGroup, 'endsgroup');

        this.endpoints.forEach((end)=>{

            this.end = this.map.createFromObjects('endpoints', end.id, 'utility', 'point', true, false, this.ledgesGroup.endsgroup);

  });

I get nothing. Console logging each this.end returns undefined, and logging each end in the forEach reveals that Phaser is receiving all of the object’s properties EXCEPT the object id:

{ 
1. height: 0
2. name: "end"
3. rectangle: true
4. rotation: 0
5. type: "end"
6. visible: true
7. width: 0
8. x: 983
9. y: 832
}

Logging this.endpoints shows the same thing: Phaser isn’t even seeing the object ids, even though the json has them:

{

                 "height":0,

                 "id":37, <=== THIS!

                 "name":"end",

                 "point":true,

                 "rotation":0,

                 "type":"end",

                 "visible":true,

                 "width":0,

                 "x":624,

                 "y":592

                },

Am I missing something? Am I making a mistake somewhere? Are the docs wrong? I’m using phaser-ce@2.18.0 and Tiled 1.7, and exporting my Tiled json files under the option of JSON map files [Tiled 1.1]. I tried exporting the tilemap with the regular JSON option and the result was the same, plus a console warning advising me to switch to the Tiled 1.1 exporter.
EDIT: if it makes any difference, the endpoint objects are Point objects in Tiled.

The JSON id field seems to be completely ignored during parsing.
Looking at the code for createFromObjects there would be a problem if there were GID’s and ID’s, If they were in the same range, GID’s would take precedence.
You could just assign id’s yourself:

for (i = 0; i < this.endpoints.length; i++) {
    this.endpoints[i].id = i + 1;
}

But then make sure there are no GID’s in the same range,

Well, good to know it wasn’t just my code, then. LOL. I decided to grab the id’s from the level json file in preload, but thanks for providing another possibility! In case anyone else finds this thread while encountering the same issue, here’s what I did:
//in Preload class:

this.assetData.tilemaps.forEach((tilemap)=>{

            this.game.load.tilemap(tilemap, `./assets/tilemaps/${tilemap}.json`, null, Phaser.Tilemap.TILED_JSON);

            this.game.load.json(tilemap, `./assets/tilemaps/${tilemap}.json`);

})

//In Game class when creating map:

this.map = this.game.add.tilemap(this._LEVELS[this._LEVEL]);

        

        this.jsonfile = this.cache.getJSON(this.map.key);

        this.jsonfile.layers.forEach((layer) => {

            if(layer.name === "endpoints") {

                this.map.endpoints = layer.objects;

            }

 });

this.map.endpoints.forEach((end)=>{

            this.endPt = this.ledgesGroup.endsgroup.create(end.x, end.y, 'point');

            this.endPt.id = end.id;

});

Probably the Phaser method shouldn’t be “fixed” as it would introduce ambiguity.

The argument could be changed to something like { id: 37 } vs. { gid: 37 }.

I do have a branch where the 11th(!) argument of createFromObjects() is a filter function.

@SHG42 could you post your map JSON if possible?

Here it is. Well, one of them, anyway! This is the map JSON for the level I was using for testing.
cave.json (239.1 KB)

1 Like

New in Phaser CE v2.19.0, you can do:

const tiledObject = tilemap.getObject(37);

or

tilemap.createFromObjects('objectLayerName', ['id', 37]);