Json tilemap from tiled not loading

Hi. Total noob here, to Phaser as well as Javascript. Winning combo, I realize. Anyway, I’m trying to learn the basics of tilemaps by following this rpg tutorial, and I’m losing my mind.

The problem is, I think, with the create function of Worldscene (I put it where it goes in the tutorial). I’m pretty sure my tilemap isn’t loading. When I try

const map = this.make.tilemap({ key: “map”});

like in the tutorial, I get an error that it can’t read property 2 of undefined. So I switch it to:

const map = this.make.tilemap(‘map’);

Which seems to help, but all I get is a black screen in the browser and warnings that my layer ID’s are invalid. I only have two layers and I’ve checked their ID’s over and over.

I’m also a bit confused about the anatomy of a Phaser project, so I’ve sort of just dumped everything into the body tag of index.html. It’s possible that or my lack of understanding the Javascript DOM may be the issue. Anyway as embarrassing as it is, here is my code:

<html>
<head>
  <title>Breaking ur first phaser game </title>
   <script src="//cdn.jsdelivr.net/npm/phaser@3.11.0/dist/phaser.js"></script>
</head>

<body>
<script type="text/ecmascript">

var BootScene = new Phaser.Class({

    Extends: Phaser.Scene,

    initialize:

    function BootScene ()
    {
        Phaser.Scene.call(this, { key: 'BootScene' });
    },

    preload: function ()
    {
        // load the resources here
        this.load.image('tiles', '../assets/level3.png')

        this.load.tilemapTiledJSON('map', '../assets/level3.json');


        this.load.spritesheet('player', '../assets/sp1.png', { frameWidth: 64, frameHeight: 64});
    },

    create: function ()
    {
        this.scene.start('WorldScene');
    }
});

var WorldScene = new Phaser.Class({

    Extends: Phaser.Scene,

    initialize:

    function WorldScene ()
    {
        Phaser.Scene.call(this, { key: 'WorldScene' });
    },

    preload: function ()
    {

    },
    create: function ()
    {
        // create your world here

        const map = this.make.tilemap('map');
        //const map = this.make.tilemap({ key: "map"});



        const tiles = map.addTilesetImage('sp2019tileset1', 'tiles', 0, 0);

        var World = map.createStaticLayer('World', 'tileset', 0, 0);
        var BelowPlayer = map.createStaticLayer('Below', 'tileset', 0, 0);

        //Create player
        this.player = this.physics.add.sprite((map.widthInPixels / 2), (map.heightInPixels / 2), 'player', 6)
        this.physics.world.bounds.width = map.widthInPixels;
        this.physics.world.bounds.height = map.heightInPixels;
        this.player.setCollideWorldBounds(true);

        //Create cursors
        this.cursors = this.input.keyboard.createCursorKeys();

        this.cameras.main.setBounds(0, 0, map.widthInPixels, map.heightInPixels);
        this.cameras.main.startFollow(this.player);
        this.cameras.main.roundPixels = true;
      },
      update: function (time, delta)
{
	this.player.body.setVelocity(0);

        // Horizontal movement
        if (this.cursors.left.isDown)
        {
            this.player.body.setVelocityX(-80);
        }
        else if (this.cursors.right.isDown)
        {
            this.player.body.setVelocityX(80);
        }

        // Vertical movement
        if (this.cursors.up.isDown)
        {
            this.player.body.setVelocityY(-80);
        }
        else if (this.cursors.down.isDown)
        {
            this.player.body.setVelocityY(80);
        }
}



});



var config = {
    type: Phaser.AUTO,
    parent: 'content',
    width: 320,
    height: 240,
    zoom: 2,
    pixelArt: true,
    physics: {
        default: 'arcade',
        arcade: {
            gravity: { y: 0 }
        }
    },
    scene: [
        BootScene,
        WorldScene

    ]
};
var game = new Phaser.Game(config);

</script>
</body>
</html>

Before I try to dig into your code, can you take a look at the “Network” tab of your dev tool, please?
If you don’t know where it is, simply press F12 for either Chrome or Firefox (not sure about others) and you should have a panel open. There also should be a “Network” tab in which you can monitor every request your page is trying to do and their results.

Refresh your page without closing this tab so the browser will record everything from the beginning and try to see if there is any error appearing. Chrome will put in red queries that didn’t work.

Moreover, how do you “execute” your code? Do you simply open this html file in your browser directly? You should use a static web server for it to work properly.

Fair point. I’m running xampp, and verified that my phaser install was working by viewing localhost before getting started. I copied the Phaser folder to htdocs. However I would not rule out the possibility that my source does not properly reference those libraries (except I don’t get any javascript run time errors in the console; just the warnings about tilemap layers).

My network tab on the console displays 13 queries; my index.html and phaser.js a twice, and then mostly my image files, and the tilemap .json file. None of these are in red though.

Edit: I should probably mention that the update function in that code works, as does the sprite. So I have a little sprite appear and can make him move around a black screen.

Happy New Year!!

I managed to get your project working with some tinkering.

My version can be found at my github here https://github.com/ppelayo1/phaser3/tree/master/pforumsHelp/squidProject

There were three problems preventing it from working.

First you needed to have //const map = this.make.tilemap({ key: “map”}); instead of the previous line.

It could not find the ID of the two layers as it didn’t know what json map to use.

*Second* you needed to set the width for the tileset. You had const tiles = map.addTilesetImage(‘sp2019tileset1’, ‘tiles’, 0, 0);

My version used 64 width and 64 height tiles so mine was const tiles = map.addTilesetImage(‘sp2019tileset1’, ‘tiles’, 64, 64);.

You could have also left it as const tiles = map.addTilesetImage(‘sp2019tileset1’, ‘tiles’). As I am pretty sure the JSON will provide the tile-set dimensions for you.

Third var World = map.createStaticLayer(‘World’, ‘tileset’, 0, 0); needs the tiles variable, and not the string tileset.

Mine was as
var World = map.createStaticLayer(‘World’, tiles, 64, 64);
var BelowPlayer = map.createStaticLayer(‘Below’, tiles, 64, 64);

The API helps greatly at understanding the capability of phaser.
The tilemap API info can be found here
https://photonstorm.github.io/phaser3-docs/Phaser.Tilemaps.Tilemap.html#addTilesetImage__anchor

I am still fairly new with phaser myself. Almost got my first ‘game’ finished that uses tilemaps. Not much more than just one screen, where you move right, dodge some enemies, then end. Still a fun experience.

I hope this helps solve your problem, let me know.

Thanks for the help! Unfortunately, I still couldn’t get it to work. When manal edits failed, I tried copying your entire file. When that didn’t work, I figured maybe there was something wrong with the json file, so I tried using yours and your level3.png. Sadly, I am still getting

Uncaught TypeError: Cannot read property '2' of undefined
at AssignTileProperties (phaser.js:123434)
at ParseJSONTiled (phaser.js:79714)

etc

That sucks…

You can try putting up your entire project folder, assets,html on github.

We can take a look at the files directly, and see if we can remedy the problem.

Been a while since I’ve messed around with Git, so that took a bit of doing. Here is everything. It’s set public so you should be able to read it.

Have you tried to reference to the newest version here?

<script src="//cdn.jsdelivr.net/npm/phaser@3.15.1/dist/phaser.js"></script>

Oddly enough, that just shrinks my black screen. I guess the newest version takes height and width in pixels a little more seriously?

I have been wondering if I’ve fully referenced the phaser libraries. Do I need to do anything more beyond include that line? If so, what is the point in even installing the library? I did put a copy of phaser.js in the same directory as my index.html just in case.

At this point, I feel like the error is most likely either in my json map or my png of said map. I’ve been playing around with tiled settings to see if I missed something important, but so far can’t find anything.

You will have to edit the Game Config

pixelArt: true will not work anymore.
Use this render: { pixelArt: true, antialias: false, autoResize: false } instead.

Thanks for the help so far. I have made that change and still get Uncaught TypeError: Cannot read property ‘2’ of undefined if I use const map = this.make.tilemap({ key: “map”});, and a black screen if I use const map = this.make.tilemap(‘map’);

First problem is you are not pathing toward your assets correctly.

The pathing is done where the script is located.
So since your script is in your HTML file you need to just do

// load the resources here
this.load.image(‘tiles’, ‘assets/level3.png’)
this.load.tilemapTiledJSON(‘map’, ‘assets/level3.json’);
this.load.spritesheet(‘player’, ‘assets/sp1.png’, {
frameWidth: 64,
frameHeight: 64
});

This will get your player to at least appear.

The second problem is your not actually loading a tileset. It is simply a image of a gameMap.

This second problem I am going to go over throughly so that you understand how to resolve this issue.

I took your level3.png and converted some of the squares into tiles, for the Tiled program. I did this with GIMP which is a image editor like photoshop but it is free.
Named the file level3properTileSet.png.
The tiles are 22 x 25.

Next I started a new map in the Tiled program which I called level03fixed.json.
Your level3.png is 640x640. So 640/22 = 29.09 tiles, so round up to 30 tiles for the width.
640/25 = 25.6 so round up to 26 tiles in height;

![help01|800x433](upload://uRTl6oaNKdaubOHuWjJN1taty0c.png) 

After creating the map, go to new tileset in the bottom right of tiled, browse and select the level3properTileSet.png.
Name it ts1 so that is would be the same as what is set in your phaser program under.
const tiles = map.addTilesetImage('ts1', 'tiles', 64, 64);

Make sure the the tile width is 22px, and tile height is set to 25px.

![help02|800x433](upload://nqCSVqVHrE6mAIKuKUe5JBV5KOt.png) 

You can now create the map anyway you want, I did a little bit trying to replicate your level03.png to demonstrate an example.
Make sure to create your layers World,Lower in Tiled and put stuff in it.
![help03|800x487](upload://jpygb7PgwOUWaEnAm3gUjt5motv.png) 


Lastly I change the paths to point toward the new files I created. I also changed these statements.

// create your world here
            //const map = this.make.tilemap('map');
            const map = this.make.tilemap({ key: "map"});
            const tiles = map.addTilesetImage('ts1', 'tiles');
            var World = map.createStaticLayer('World', tiles);
            var BelowPlayer = map.createStaticLayer('Below', tiles);
			
			Don't need to put anynumbers in the addtilesetImage as the JSON will provide it, but if you did it would need to be 22,25 as that is what the tile dimensions are.
			
			Not for createStaticLayer the numbers will simply determine where on the canvas the layer will be moved to. So 64,64 would move it 64 to the right and 64 down. Can just leave it blank so it defaults 0.
			
			I am gonna throw everything up on github for you to look at too. But the map is now working and the character can move, just he doesn't have any animation doing so.

My post didn’t turn out as I intended, I included the images in the file I uploaded under assets.

If you need any further help feel free to ask. Maps are a pain to get, and it took me a while to understand them.

Thanks very much for the help! After much hacking at it myself, I gave up and just downloaded your level30fixed.json and your tileset. There was something else wrong with my code somewhere (surprise surprise) that eventually I gave up looking for and just used your version of index.html, and now everything finally works.

I kinda want to lock it in a box so I can’t break it.

Maybe you can help me pinpoint how I went wrong in the first place? I understand now that the image file is a tileset, and not just an image of the level. But I created everything in a pixel art program, so my tiles all SHOULD have been 32x32. I then used Tiled to make the map. And I’m just not sure how they got…clipped? distorted?

Thanks again for the help! I was ready to put my fist through my screen (this is why I only code as a hobby).

The main problem I noticed was that you didn’t have a tileset, but just an image of what you wanted the game map to look like.

Free tilesets are available here https://www.kenney.nl/assets?q=2d.
That is where I started on learning tilesets, by implementing already made ones.

It is good to break something, and then fix it. Fixing our mistakes is a great learning experience, although frustrating.

hey Patrick, i couldn’t help but notice that this issue i’m having with my phaser game project is very similar to this one you help solve. i know this was over a year a go but i was wondering if you could help as well. i’ve tried almost every tutorials online but none seem to work or be willing to understand my codes/layout(not complicated just a multilevel game) enough to suggest a working solution.
i like the way you explained it in the upper thread and would like to understand my problem and fix it if you have time. thanks!