Sign in to follow this  
aylictal

rendering objects from tile map

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? :(

Share this post


Link to post
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.

Share this post


Link to post
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!

Share this post


Link to post
Share on other sites

Having still a little issues when I sat down and tried to access the tilelayer data.

Where are you getting these last two arguments from?

 

'characters', m.gid - charTilesetRaw.firstgid

Thanks again.

Share this post


Link to post
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.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this  

  • Recently Browsing   0 members

    No registered users viewing this page.