Jump to content

rendering objects from tile map


aylictal
 Share

Recommended Posts

Hello-

I've tried my best to follow the phaser 3 guides, but none are trying to do what I need my game to do, so I looked at this guide: https://phaser.io/examples/v2/groups/depth-sort but am having trouble loading objects into my game from an object layer, which this example was loading from a sprite sheet.

If I console.log(this.map.objects) I am successfully getting this back in return:
[ObjectLayer]

Which is definitely good. It means my object layer successfully got imported.

If I JSON.stringify(this.map.objects[0], null, '\t') I get the following:
 

"{
	"name": "Object Layer 1",
	"opacity": 1,
	"properties": [
		{
			"name": "tree",
			"type": "string",
			"value": "tree"
		}
	],
	"propertyTypes": {},
	"type": "objectgroup",
	"visible": true,
	"objects": [
		{
			"id": 26,
			"name": "tree",
			"type": "",
			"rotation": 0,
			"visible": true,
			"x": 367.454545454545,
			"y": 192,
			"width": 16,
			"height": 16,
			"gid": 1260,
			"flippedHorizontal": false,
			"flippedVertical": false,
			"flippedAntiDiagonal": false
		},
		{
			"id": 29,
			"name": "tree",
			"type": "",
			"rotation": 0,
			"visible": true,
			"x": 368,
			"y": 208,
			"width": 16,
			"height": 16,
			"gid": 1310,
			"flippedHorizontal": false,
			"flippedVertical": false,
			"flippedAntiDiagonal": false
		},
		{
			"id": 30,
			"name": "tree",
			"type": "",
			"rotation": 0,
			"visible": true,
			"x": 368,
			"y": 224,
			"width": 16,
			"height": 16,
			"gid": 1360,
			"flippedHorizontal": false,
			"flippedVertical": false,
			"flippedAntiDiagonal": false
		},
		{
			"id": 31,
			"name": "tree",
			"type": "",
			"rotation": 0,
			"visible": true,
			"x": 368,
			"y": 240,
			"width": 16,
			"height": 16,
			"gid": 1410,
			"flippedHorizontal": false,
			"flippedVertical": false,
			"flippedAntiDiagonal": false
		},
		{
			"id": 34,
			"name": "tree",
			"type": "",
			"rotation": 0,
			"visible": true,
			"x": 400,
			"y": 256,
			"width": 16,
			"height": 16,
			"gid": 1410,
			"flippedHorizontal": false,
			"flippedVertical": false,
			"flippedAntiDiagonal": false
		},
		{
			"id": 35,
			"name": "tree",
			"type": "",
			"rotation": 0,
			"visible": true,
			"x": 400,
			"y": 240,
			"width": 16,
			"height": 16,
			"gid": 1360,
			"flippedHorizontal": false,
			"flippedVertical": false,
			"flippedAntiDiagonal": false
		},
		{
			"id": 36,
			"name": "tree",
			"type": "",
			"rotation": 0,
			"visible": true,
			"x": 400,
			"y": 224,
			"width": 16,
			"height": 16,
			"gid": 1310,
			"flippedHorizontal": false,
			"flippedVertical": false,
			"flippedAntiDiagonal": false
		},
		{
			"id": 37,
			"name": "tree",
			"type": "",
			"rotation": 0,
			"visible": true,
			"x": 400,
			"y": 208,
			"width": 16,
			"height": 16,
			"gid": 1260,
			"flippedHorizontal": false,
			"flippedVertical": false,
			"flippedAntiDiagonal": false
		}
	]
}"

How can I actually render this to the screen?  I have tried the following:

 

class stage extends Phaser.Scene {
    preload(){
        this.load.tilemapTiledJSON('map', 'assets/map.json');
        this.load.image('backgroundtiles', 'assets/backgroundtiles.png');
    }

    create(){
        this.map = this.make.tilemap({key: 'map'});
        this.tileset = this.map.addTilesetImage('backgroundtiles');
        this.layer = this.map.createStaticLayer('Tile Layer 1', this.tileset, 0, 0).setScale(this.scale);
        this.createtrees();

    createtrees(){
        this.trees = this.add.group();
        this.map.objects[0].objects.forEach(e=>{
              this.trees.create(e.x, e.y)
        });
    }
}

This renders the black squares with the green cross through them because it doesn't know what graphic to load.  Is this something in Tiled I need to provide to phaser?

Also of some other note, the graphics themselves even though they were rendered with a bad image, were also loaded with incorrect positions.  What is going on? :(

Link to comment
Share on other sites

This is one noob to another and may not be the best possible answer.

I think you'll need to be more explicit in making your object layer into images. Note that Tiled object layers (including your JSON above) don't say anything about tilesets. They're just data objects that don't necessarily have anything to do with images at all. If you want to turn them into images you'll have to write some code. (It is interesting to me that you even got the green cross with the above.)

In my case I put static stuff in the tile layers, and monsters in the object layer. Monsters are converted to sprites. Here's a snippet of what I'm doing that may help you get on a track:

                charObjects
                    .filter(m => m.gid !== playerGid)
                    .forEach(function (m) {
                        // again, spritesheet frame uses same indexing as tiled, except tiled has the gid offset.
                        var monsterSprite = scene.add.tileSprite(m.x + 16, m.y - 16, 32, 32, 'characters', m.gid - charTilesetRaw.firstgid);
                        var spriteTile = sceneLayers[backgroundLayerName].tilemapLayer.getTileAtWorldXY(monsterSprite.x, monsterSprite.y);
                        monsters.push({ name: charTilesData[m.gid].name, x: spriteTile.x, y: spriteTile.y, sprite: monsterSprite });
                    });

important, my charObjects here is not the raw data that came directly out of Tiled, but rather a descendant of that object layer data that has already been processed for my purposes.

Obviously a lot of context is left out here, but you can see the basic idea of making a sprite based on the object data using `scene.add.tileSprite()`. Details likely different for you.

 

Quote

 

Also of some other note, the graphics themselves even though they were rendered with a bad image, were also loaded with incorrect positions.  What is going on? :(

 

Phaser's x/y is different than Tiled's. "in Phaser 3 all Game Objects are positioned based on their center by default. " https://phaser.io/tutorials/making-your-first-phaser-3-game/part2

In that link Rich talks about using setOrigin() to change this. In my case I just applied an offset to the sprite creation as you can see above (+16/-16). (That hardcoding is only temporary, btw.)

Anyway, I hope this helps somewhat.

Link to comment
Share on other sites

I see you are accessing the gid, which I have access too as well! This is what I thought the linker was, or the binder to the tileset.  I'll tinker around with your example and see if I can get anything to load using it.

Much appreciated dude thanks!

Link to comment
Share on other sites

'characters' refers to a spritesheet that I created in preload():

                this.load.spritesheet('characters', '/maps/characters.png', { frameWidth: 32, frameHeight: 32 });

m.gid is the gid of the object from the object layer, you've got one in your posted JSON and I would guess there is always one (or at least for tile-based objects). I parseInt() these gids, you may want/need to also.

charTilesetRaw.firstgid comes from the tileset, that I have previously added to the tilemap as a dynamic layer:

                var charTilesetRaw = map.tilesets.filter(t => t.name === 'characters')[0];

The firstgid property comes from Tiled, I didn't do anything special to add it or make it accessible.

Link to comment
Share on other sites

 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...