Skip to content

Improve support for TiledImageCollection - as it currently assumes all tilesets will be the maximum size of the image in the collection #6990

Closed
@stickleprojects

Description

@stickleprojects

Version

  • Phaser Version:
  • 3.87.0
  • Operating system:
  • Windows 11
  • Browser:

Description

When loading a tiled map with imagecollection, and when your images are different sizes. The tilesets are incorrectly created with the same size as the maximum sized image in your tileset.
Following the excellent work recently to add support for imagecollection, this bugfix to tweak that to support tilesets from images

Example Test Code


import { Scene } from "phaser";

export class AtlasScene extends Scene {
    playscene: Scene;
    map: Phaser.Tilemaps.Tilemap;
    bk: Phaser.Tilemaps.TilemapLayer | null;

    constructor() {
        super('AtlasScene');

    }

    preload() {
        this.load.setPath('assets');

        this.load.tilemapTiledJSON('c64map', 'maps\\atlasmap1.tmj');

        const imagesToLoad = [
            'candle5'
            , 'candle6'
            , 'clock1'
            , 'portrait2'
            , 'portrait3'
            , 'shield1'
            , 'shield2'
            , 'shield3'
            , 'shield4'
        ]

        imagesToLoad.forEach((i: string) => {
            const filename = i + '.png'
            this.load.image(filename, 'c64spritesheets\\' + filename);
        })
    }
    create() {

        this.map = this.make.tilemap({ key: 'c64map' });

        let loadedTilesets: any[] = []
        this.map.imageCollections.forEach((ic: Phaser.Tilemaps.ImageCollection) => {
            ic.images.forEach((img: any) => {

                // the img.image is "../c64spritesheets/candle5.png"
                // in the atlas the key is "candle5.png"

                let tmpname = img.image;
                tmpname = tmpname.replace('../c64spritesheets/', '');
                if (this.textures.exists(tmpname)) {
                    const tmi = this.map.addTilesetImage(img.image, tmpname);
                    loadedTilesets.push(tmi);
                }

            });
        })

        // problem the ParseTilesets function used to parse the tilemap, incorrectly creates imagecollection
        // with a single width for all tiles, it takes the tilewidth and tileheight as the imageheight and imagewidth on the tileset
        // and it ignores the height+width of each individual tile
        // so we need to extend the support for this

      
        this.bk = this.map.createLayer('Tile Layer 1', loadedTilesets, 0, 0);

        const debugWindow = this.add.graphics();
        this.map.renderDebug(debugWindow); // large squares of colour rendered onscreen
    }
}
`

in the tiled format, each image does have a size:

  "name":"atlastileset1",
         "spacing":0,
         "tilecount":23,
         "tileheight":474,
         "tiles":[
                {
                 "id":0,
                 "image":"..\/c64spritesheets\/candle5.png",
                 "imageheight":48,
                 "imagewidth":32
                }, 
                {
                 "id":1,
                 "image":"..\/c64spritesheets\/candle6.png",
                 "imageheight":48,
                 "imagewidth":32
                }, 
                

Additional Information

Recommendation:

  • imagecollection.addimage - take in the imagewidth and height as parameters from the json parser
  • phaser.tilemaps.parsers.tiled.builditlesetindex - currently uses imagecollection.imageWidthximageHeight for each tileset, instead use the image.width and image.height newly added

Screenshots below show the tiled map editor
, and the debugrender from the code above.
, and the imagecollection

map1_debugrender
map1
imagecollection

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions