Jump to content

Phaser Multiple layers not rendering in screen with Tiled json map data


Recommended Posts

Hello guys! This is my first time here. I have looked through a lot of posts already trying to find the answer, but for some reason nothing is working for me!!! I am using tiled to get the map data and I have included it just fine since I was following the tutorials. So the first layer shows, but as soon as I create another layer that has my objects that will collide with the user, they don't appear. I have no idea what I am doing wrong. I am using the responsive template that came with phaser, which is why everything is in different files and stuff.


This is my game.js

BasicGame.Game = function (game) {    //	When a State is added to Phaser it automatically has the following properties set on it, even if they already exist:    this.game;		//	a reference to the currently running game    this.add;		//	used to add sprites, text, groups, etc    this.camera;	//	a reference to the game camera    this.cache;		//	the game cache    this.input;		//	the global input manager (you can access this.input.keyboard, this.input.mouse, as well from it)    this.load;		//	for preloading assets    this.math;		//	lots of useful common math operations    this.sound;		//	the sound manager - add a sound, play one, set-up markers, etc    this.stage;		//	the game stage    this.time;		//	the clock    this.tweens;    //  the tween manager    this.state;	    //	the state manager    this.world;		//	the game world    this.particles;	//	the particle manager    this.physics;	//	the physics manager    this.rnd;		//	the repeatable random number generator    this.player;    this.cursors;    this.map;    this.ground_layer;    this.tree_layer;    this.building_layer;};BasicGame.Game.prototype = {    create: function () {        ////  We're going to be using physics, so enable the Arcade Physics system        this.game.physics.startSystem(Phaser.Physics.ARCADE);        //this.map = this.add.tilemap('littleroot');        this.map = this.game.add.tilemap('littleroot');        this.map.addTilesetImage('tiles', 'gameTiles');        this.ground_layer = this.map.createLayer('ground');        this.tree_layer = this.map.createLayer('trees');        this.building_layer = this.map.createLayer('buildings');        //this.map.setCollisionBetween(1, 9962, true, 'trees');        //this.map.setCollisionBetween(1, 9962, true, 'buildings');        this.ground_layer.resizeWorld();        //this.tree_layer.resizeWorld();        //// The player and its settings        this.player = this.game.add.sprite(32, this.game.world.height - 150, 'dude');        //        ////  We need to enable physics on the player        this.game.physics.arcade.enable(this.player);        //this.player.body.collideWorldBounds = true;        ////  Our two animations, walking left and right.        this.player.animations.add('left', [0, 1, 2, 3], 10, true);        this.player.animations.add('right', [5, 6, 7, 8], 10, true);        ////  Our controls.        this.camera.follow(this.player);        this.cursors = this.game.input.keyboard.createCursorKeys();    },    update: function () {        this.game.physics.arcade.collide(this.player, this.tree_layer);        this.game.physics.arcade.collide(this.player, this.building_layer);        //  Reset the players velocity (movement)        this.player.body.velocity.x = 0;        this.player.body.velocity.y = 0;        if (this.cursors.left.isDown)        {            //  Move to the left            this.player.body.velocity.x = -150;            this.player.animations.play('left');        }        else if (this.cursors.right.isDown)        {            //  Move to the right            this.player.body.velocity.x = 150;            this.player.animations.play('right');        }        else if (this.cursors.up.isDown) {            //  Move up            this.player.body.velocity.y = -150;            //this.player.animations.play('up');        }        else if (this.cursors.down.isDown)        {            //  Move down            this.player.body.velocity.y = 150;            //this.player.animations.play('down');        }        else        {            //  Stand still            this.player.animations.stop();            this.player.frame = 4;        }    },    quitGame: function (pointer) {        //	Here you should destroy anything you no longer need.        //	Stop music, delete sprites, purge caches, free resources, all that good stuff.        //	Then let's go back to the main menu.        this.state.start('MainMenu');    },};

This is my preloader.js

BasicGame.Preloader = function (game) {	this.background = null;	this.preloadBar = null;	this.ready = false;};BasicGame.Preloader.prototype = {	preload: function () {		// These are the assets we loaded in Boot.js		// Load tile map data for the tile set		this.load.tilemap('littleroot', 'assets/tiles/pk_emerald_map.json', null, Phaser.Tilemap.TILED_JSON);		// Load the tileset		this.load.image('gameTiles', 'assets/tiles/pk_emerald_map.png');		this.load.spritesheet('dude', 'assets/sprites/dude.png', 32, 48);	},	create: function () {		this.state.start('MainMenu');	}};

I also tried uploading my json file, but I got this error: 'You aren't permitted to upload this kind of file'. So hopefully it's a code error and nothing to do with the json! :(


I am also getting these warnings:

1) Phaser.Tileset - image tile area is not an even multiple of tile size phaser.min.js:24

2) Tilemap.createLayer: Invalid layer ID given: null phaser.min.js:24 


Maybe these have something to do with it? I know I am missing something fundamental here because I looked through many tutorials and all of their layers work. Thanks for the help guys!

Link to comment
Share on other sites

Yes I have tried that. I am still getting the same errors along with the error: 'Uncaught TypeError: Cannot read property resizeWorld of undefined.' If I comment out the resize_world line, then I still get the same errors as before but the screen is black.

Link to comment
Share on other sites

  • 1 month later...

I have a similar problem. I try to create two layers from a Tiled-exported .json map, but it gives me the exceptions:


Tilemap.createLayer: Invalid layer ID given: null           phaser.js:89983:13
TypeError: layer is undefined                                        game.js:49:9
TypeError: cursors is undefined                                    game.js:87:1


Here are my preload and create functions:

        preload: function () {            game.load.tilemap('level1', 'assets/maps/level1/level1test.json', null, Phaser.Tilemap.TILED_JSON);            game.load.image('grottaTiles', 'assets/maps/Tilesets/grotta.png');            game.load.image('block', 'assets/sprites/blocks/block.png');            game.load.image('player', 'assets/sprites/characters/BB2.png');            game.load.image('Enemy1','assets/sprites/characters/Enemies/BlueBox.png');        },             create: function () {            game.physics.startSystem(Phaser.Physics.P2JS);            game.physics.p2.updateBoundsCollisionGroup(true);            game.physics.p2.setImpactEvents(true);            game.physics.p2.gravity.y = 1400;                 backgroundLayerGroup    = game.add.group();            playerGroup             = game.add.group();            enemyGroup              = game.add.group();            foregroundLayerGroup    = game.add.group();                 enemyCollisionGroup     = game.physics.p2.createCollisionGroup();            playerCollisionGroup    = game.physics.p2.createCollisionGroup();            platformCollisionGroup  = game.physics.p2.createCollisionGroup();            worldCollisionGroup     = game.physics.p2.createCollisionGroup();                      map = new Phaser.Tilemap(game, 'level1');            map.addTilesetImage('grotta', 'grottaTiles');                 //This is where the problem occurs.            layer2 = map.createLayer('Background', 320, 320, backgroundLayerGroup);            layer2.resizeWorld();                 //If I comment out the two lines below, the 'Background' layer renders just fine and I get no exceptions.            layer = map.createLayer('Foreground', 320, 320, foregroundLayerGroup);            layer.resizeWorld();                 //However, if I comment out the creation of the 'Background' layer and leave the creation of the 'Foreground' layer,            //the same exceptions are thrown as when I try to create both.            //Except these two switch places:            //       TypeError: layer is undefined                               game.js:49:9            //       Tilemap.createLayer: Invalid layer ID given: null           phaser.js:89983:13                      map.setCollision([1, 11, 12, 13, 21, 22], true, layer);            tileBodies = game.physics.p2.convertTilemap(map, layer);            game.physics.p2.convertCollisionObjects(map, 'Collision');                 for (var i = 0; i < tileBodies.length; i++) {                tileBodies[i].setCollisionGroup(platformCollisionGroup);                tileBodies[i].collides([playerCollisionGroup, enemyCollisionGroup]);            }                 player = createPlayer(160, 60, playerGroup, game);                 block = game.add.sprite(288, 320, 'block');            game.physics.p2.enable(block);                 enemy = new Phaser.Sprite(game, 160, 160, 'Enemy1');            game.physics.p2.enable(enemy);            enemyGroup.add(enemy);            enemy.body.fixedRotation = true;            enemy.body.setCollisionGroup(enemyCollisionGroup);            enemy.body.collides([playerCollisionGroup, platformCollisionGroup]);                 game.camera.follow(player);                 cursors = game.input.keyboard.createCursorKeys();        },


Here's a snapshot of my Tiled window with the testmap open.



I'm using Phaser 2.4.4

Any replies are appreciated.

Link to comment
Share on other sites

Are you working off of a spritesheet? If so you could try using


    this.map.addTilesetImage('tiles_spritesheet', 'gameTiles');
I am not quite sure but if you are using Tiled and just uploading individual .png files it could cause issues..... atleast it did for me. I would try breaking your layers into only two seperate groups in Tiled to see if that fixes it. Simply use this.backgroundLayer and this.blockedLayer. Any tile you want the player in game to have collision with is what you put in this.blockedLayer. An example would be.
this.map = this.game.add.tilemap('level1');
    //the first parameter is the tileset name as specified in Tiled, the second is the key to the asset
    this.map.addTilesetImage('tiles_spritesheet', 'gameTiles');
    //create layers
    this.backgroundlayer = this.map.createLayer('backgroundLayer');
    this.blockedLayer = this.map.createLayer('blockedLayer');
    //collision on blockedLayer
    this.map.setCollisionBetween(1, 100000, true, 'blockedLayer');
    //resizes the game world to match the layer dimensions
Not sure if this helps but its how I have been setting mine up and I have not had any issues thus far.
Link to comment
Share on other sites

I tried to do it in @Get_Bentley's way without success. I'm still getting 'Tilemap.createLayer: Invalid layer ID given: null' , which seems to be the root of the problem. I also tried using number indexes for the layers instead of passing in their names as strings, but that didn't work at all.


This is the layers array in the .json file:


 "layers":[        {         "data":"DgAAAA4AAAAOAAAADgAAAA4AAAAOAAAADgAAAA4AAAAOAAAADgAAAA4AAAAOAAAADgAAAA4AAAAOAAAADgAAAA4AAAAOAAAADgAAAA4AAAAOAAAADgAAAA4AAAAOAAAADgAAAA4AAAAOAAAADgAAAA4AAAAOAAAADgAAAA4AAAAOAAAADgAAAA4AAAAOAAAADgAAAA4AAAAOAAAADgAAAA4AAAAOAAAADgAAAA4AAAAOAAAADgAAAA4AAAAOAAAADgAAAA4AAAAOAAAADgAAAA4AAAAOAAAADgAAAA4AAAAOAAAADgAAAA4AAAAOAAAADgAAAA4AAAAOAAAADgAAAA4AAAAOAAAADgAAAA4AAAAOAAAADgAAAA4AAAAOAAAADgAAAA4AAAAOAAAADgAAAA4AAAAOAAAADgAAAA4AAAAOAAAADgAAAA4AAAAOAAAADgAAAA4AAAAOAAAADgAAAA4AAAAOAAAADgAAAA4AAAAOAAAADgAAAA4AAAAOAAAADgAAAA4AAAAOAAAADgAAAA==",         "encoding":"base64",         "height":10,         "name":"Background",         "opacity":1,         "type":"tilelayer",         "visible":true,         "width":10,         "x":0,         "y":0        },         {         "data":"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFwAAAAsAAAALAAAACwAAAAsAAAAYAAAAAAAAAAAAAAAAAAAAAAAAACEAAAANAAAADQAAAA0AAAANAAAAIgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==",         "encoding":"base64",         "height":10,         "name":"Foreground",         "opacity":1,         "type":"tilelayer",         "visible":true,         "width":10,         "x":0,         "y":0        },         {         "draworder":"topdown",         "height":10,         "name":"Collision",         "objects":[                {                 "height":0,                 "id":1,                 "name":"",                 "polyline":[                        {                         "x":-8,                         "y":0                        },                         {                         "x":18,                         "y":14                        },                         {                         "x":21,                         "y":30                        },                         {                         "x":11,                         "y":54                        },                         {                         "x":-16,                         "y":63                        }],                 "properties":                    {                    },                 "rotation":0,                 "type":"",                 "visible":true,                 "width":0,                 "x":236,                 "y":129                },                 {                 "height":0,                 "id":2,                 "name":"",                 "polyline":[                        {                         "x":0,                         "y":0                        },                         {                         "x":-19,                         "y":10                        },                         {                         "x":-28,                         "y":30                        },                         {                         "x":-23,                         "y":46                        },                         {                         "x":-15,                         "y":60                        },                         {                         "x":7,                         "y":64                        }],                 "properties":                    {                    },                 "rotation":0,                 "type":"",                 "visible":true,                 "width":0,                 "x":92,                 "y":127                }],         "opacity":1,         "type":"objectgroup",         "visible":true,         "width":10,         "x":0,         "y":0        }],


I tried putting 0 instead of 'Background', 1 instead of 'Foreground' and 2 instead of 'Collision', and the other way around, but I got a new exception:

        TypeError: this.layers[layer] is undefined             phaser.js:90352:2


Just using 0 instead of 'Background' works though, if I comment out the creation of the foreground layer.


It's all very weird. I'm certain I'm inputting the correct strings to the createLayer function, but somewhere along the way in phaser.js, the layer ID seems to become null. There shouldn't be anything wrong with the foreground layer, rather, I feel like phaser has trouble identifying the layer from the .json correctly.

Link to comment
Share on other sites

  • 3 weeks later...

1) as I have already mentioned you can't createLayer on an object layer . That one will give you the null ID error

2) if you're saying foreground tile layer is giving you an error , try CSV encoding instead of base64 (but still export as json) and see if that works


The CSV encoding also works for me!


Btw what do you mean by object layer? In Tiled, how do I know if my layer is an object layer or not?

Link to comment
Share on other sites

  • 2 weeks later...



I'm just learning Phaser right now -- and am attempting to use Tiled to create a tilemap with multiple layers (one for my background, and two for different collision objects -- dunno if that's right, but it's what I'm trying). Anyway, I just could not figure out why I'm getting always the `invalid layer ID` error. In debugging, within the createLayer() method, this.layers array (representing the layers of the tilemap as read from the JSON file) only had 1 layer listed.


I debugged and Phaser actually was reading all three layers properly when it gets the json data; at some point, though, it is lost.


I've checked out the previous version, 2.4.3, and it is reading just fine. I suspect this is a regression in Phaser 2.4.4?

Link to comment
Share on other sites


  • Recently Browsing   0 members

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