NarutoProgrammer
NarutoProgrammer

Reputation: 115

How can I load an exported Tileset (image collection) from Tiled in Phaser 3?

I want to load an image collection tileset into my phaser game. I know that with tilesets that are just one image you can just load that image into phaser, but what about an image collection? In Tiled I saw the options to export that tileset as either .tsx or .json, but I don't know if that helps in my case. The reason I need this is because I have some objects that are too big to be used as tiles. I can load them into Tiled and place them like I want to, but obviously they don't show up in my game, unless I can import that tileset into phaser. Does anyone know how to do that, or maybe you know a better option than using an image collection?

Upvotes: 2

Views: 1686

Answers (1)

winner_joiner
winner_joiner

Reputation: 14695

Well after some tests, and updating my Tiled version to 1.9.2, it seems there is an pretty simple way.

  1. As long as the tileset collection is marked as "Embeded in map" enter image description here
    (I could have sworn, this checkbox was hidden/deactivated, when selecting "Collection of Images", in my early Tiled version)

  2. Export the map as json

  3. Load map and tile-images

    preload() { 
      this.load.tilemapTiledJSON('map', 'export.tmj');
      this.load.image('tile01', 'tile01.png');
      this.load.image('tile02', 'tile02.png');
      ...
    }
    
  4. create Phaser TileSets, just use the filename from the json as the tilsetName (this is the "tricky" part, atleast for me)

    create() {
      var map = this.make.tilemap({ key: 'map' });
      var img1 = map.addTilesetImage( 'tile01.png', 'tile01');
      var img2 = map.addTilesetImage( 'tile02.png', 'tile02');
      ...
    
      // create the layer with all tilesets
      map.createLayer('Tile Layer 1', [img1, img2, ...]);
      ... 
    }
    

This should work, atleast with a "Collection of images", with images that have a size of 8x8 pixel (since I don't know the needed/intended Images size, I didn't want to waste time testing various images-sizes needlessly).

Here a small demo:
(due to CORS-issues the map data is inserted as jsonObject and the textures are generate and not loaded)

const mapJsonExport = {"compressionlevel":-1,"height":10,"infinite":false,"layers":[{"compression":"","data":"AQAAAAEAAAACAAAAAgAAAAEAAAACAAAAAgAAAAIAAAACAAAAAgAAAAIAAAACAAAAAgAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAIAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAACAAAAAQAAAAEAAAACAAAAAgAAAAEAAAABAAAAAgAAAAIAAAABAAAAAgAAAAIAAAACAAAAAgAAAAEAAAACAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAIAAAACAAAAAgAAAAEAAAACAAAAAgAAAAEAAAACAAAAAQAAAAEAAAACAAAAAQAAAAEAAAABAAAAAQAAAAEAAAACAAAAAgAAAAEAAAABAAAAAgAAAAEAAAABAAAAAQAAAAEAAAACAAAAAQAAAAIAAAACAAAAAgAAAAEAAAABAAAAAgAAAAEAAAACAAAAAgAAAAIAAAACAAAAAgAAAAEAAAABAAAAAgAAAAIAAAACAAAAAgAAAAEAAAACAAAAAQAAAA==","encoding":"base64","height":10,"id":1,"name":"Tile Layer 1","opacity":1,"type":"tilelayer","visible":true,"width":10,"x":0,"y":0}],"nextlayerid":2,"nextobjectid":1,"orientation":"orthogonal","renderorder":"right-down","tiledversion":"1.9.2","tileheight":8,"tilesets":[{"columns":0,"firstgid":1,"grid":{"height":1,"orientation":"orthogonal","width":1},"margin":0,"name":"tiles","spacing":0,"tilecount":2,"tileheight":8,"tiles":[{"id":0,"image":"tile01.png","imageheight":8,"imagewidth":8},{"id":1,"image":"tile02.png","imageheight":8,"imagewidth":8}],"tilewidth":8}],"tilewidth":8,"type":"map","version":"1.9","width":10};

var config = {
    width: 8 * 10,
    height: 8 * 10,
    zoom: 2.2,
    scene: { preload, create }
}; 

function preload() {
    // loading inline JSON due to CORS-issues with the code Snippets
    this.load.tilemapTiledJSON('map', mapJsonExport);    
    
    // generating texture instead of loading them due to CORS-issues with the code Snippets
    let graphics = this.make.graphics({add: false});
    graphics.fillStyle(0xff0000);
    graphics.fillRect(0, 0, 8, 8);
    graphics.generateTexture('tile01', 8, 8);
    
    graphics.fillStyle(0x000000);
    graphics.fillRect(0, 0, 8, 8);
    graphics.generateTexture('tile02', 8, 8);
}

function create () {
    
    let map = this.make.tilemap({ key: 'map' });
    let img1 = map.addTilesetImage( 'tile01.png', 'tile01');
    let img2 = map.addTilesetImage( 'tile02.png', 'tile02');

    map.createLayer('Tile Layer 1', [img1, img2], 0, 0);
}

new Phaser.Game(config);
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/phaser.js"></script>

Upvotes: 2

Related Questions