mhcdotcom Posted October 18, 2018 Share Posted October 18, 2018 Hey Folks, I hope you can help. I am fairly new to Phaser 3 and am currently working on a platformer where my character can run, jump and collect collectibles. My game is modularised through WebPack everything else is plain JS along with the Phaser 3 framework. I am using Tiled where I export my levels as json files and the initial level loads perfectly with all collision tiles in place and working as expected. I've hit a road block with loading/starting new levels. I'll try and explain with my code to clarify. I've reduce the code significantly to make it easier to read. main.js: Entry file // Main.js import 'phaser'; import { Cave } from 'scenes/cave'; import { Playground } from 'scenes/playground'; var config = {...}, scene: [Cave,Playground] }; var game = new Phaser.Game(config); Cave.js. For the sake of conciseness, I've placed the this.scene.start in the update function so the new scene initialisation happens immediately. MapSetup function is further down. // Cave.js import 'phaser'; import MapSetup from 'modules/map-setup.js'; import CollectibleSetup from 'modules/collectible-setup.js'; const mapSetup = new MapSetup(); const collectibleSetup = new CollectibleSetup(); export class Cave extends Phaser.Scene { constructor () {super('Cave')} preload() { this.load.tilemapTiledJSON('map', 'assets/levels/cave/cave.json');// map made with Tiled in JSON format this.load.spritesheet('cave', 'assets/levels/cave/cave.png', {frameWidth: 64, frameHeight: 64});// tiles in spritesheet } create() { // Setup up map for this scene/level var mapObj = mapSetup.sceneMap(this, 'map', 'cave', 'world') this.map = mapObj.map; this.physics.add.overlap(this.player, this.stars, collectibleSetup.collectStar, null, this); }// create update () { this.scene.start('Playground') } Playground.js // Playground.js export class Playground extends Phaser.Scene { constructor () {super('Playground')} preload() { this.load.tilemapTiledJSON('map', 'assets/levels/playground/map.json');// map made with Tiled in JSON format this.load.spritesheet('tiles', 'assets/levels/playground/tiles.png', {frameWidth: 70, frameHeight: 70});// tiles in spritesheet } create() { // Setup up map for this scene/level var mapObj = mapSetup.sceneMap(this, 'map', 'tiles', 'World') this.map = mapObj.map; this.physics.add.overlap(this.player, this.stars, collectibleSetup.collectStar, null, this); }// create } MapSetup.js. The issue occurs here when the PlayGround scene is initiated. import 'phaser'; export default class MapSetup { sceneMap (ctx, key, tileSetImage, dynamicLayer) { // Map var map = ctx.make.tilemap({key: key}); console.log('map',map) // tiles for the ground layer - tilesets.name` var groundTiles = map.addTilesetImage(tileSetImage); // create the ground layer - layers[i].name var groundLayer = map.createDynamicLayer(dynamicLayer, groundTiles, 0, 0); // the player will collide with this layer groundLayer.setCollisionByExclusion([-1]); // set the boundaries of our game world ctx.physics.world.bounds.width = groundLayer.width; ctx.physics.world.bounds.height = groundLayer.height; return {map:map, groundTiles:groundTiles, groundLayer:groundLayer} } } I'll try and explain the issue as I understand it. When Playground is initiated, the following error fires in the console and it's because the the groundTiles & groundLayer variables return null so the setCollisionByExclusion doesn't work. When I console.log the map variable that get's assigned in the sceneMap function it returns: The tileset name is still referencing the cave json object and not the playground one. I don't understand why that is. My understanding is that a scene is automatically stopped when a new scene is started and that each scene is it's own class so i'm a bit baffled as to why previous references are still in place. What am I missing? Any help would be much appreciated. Thanks, All Moe Link to comment Share on other sites More sharing options...
samme Posted October 18, 2018 Share Posted October 18, 2018 You should use different cache keys for the two tilemaps. Link to comment Share on other sites More sharing options...
mhcdotcom Posted October 18, 2018 Author Share Posted October 18, 2018 Thanks @samme I think I figured it out. The issue is my misunderstanding of how Tiled is intended to be incorporated into Phaser's framework. I have 2 maps(JSON files) built out from 2 different Tiled files. Phaser seems to be intended to load 1 tilemap instance that is used across an entire game build. // Where the mapObj variable is assigned in Playground.js var mapObj = mapSetup.sceneMap(this, 'map', 'tiles', 'World') // The 'tiles' reference should remain the same as what is assigned in the initial Scene(i.e. 'cave') var mapObj = mapSetup.sceneMap(this, 'map', 'cave', 'World') I thought a new instance of the tilemap would be created when a new scene starts but that doesn't seem to be the case as the name 'cave' for the tileset in the console is used and not 'tiles' when the Playground scene starts. It does makes working with Tiled and building/editing levels more maintainable but wasn't very intuitive to a beginner like me. If there is anything I'm off the mark with, please let me know. Link to comment Share on other sites More sharing options...
samme Posted October 19, 2018 Share Posted October 19, 2018 Loading a tilemap file and creating/instantiating a Tilemap object are different. You can load as many tilemap files as you need, as long as you use distinct keys. It doesn't matter which scene you load them in, they're all stored in a single game cache. You can create a Tilemap object from any tilemap file already in the cache. The map belongs to the scene and lasts only as long as the scene does. blackhawx 1 Link to comment Share on other sites More sharing options...
Recommended Posts