From 37767ebde1f2301940e733c87a038a6062a1a035 Mon Sep 17 00:00:00 2001 From: Michael Hadley Date: Fri, 1 Dec 2017 13:24:37 -0600 Subject: [PATCH] Tidy: fix v2 linting errors and move Tiled parser bits into modules --- .../parsetiledjson/AssignTileProperties.js | 54 +++ .../parsetiledjson/BuildTilesetIndex.js | 52 +++ .../parsetiledjson/ParseImageLayers.js | 30 ++ .../parsetiledjson/ParseObjectLayers.js | 39 +++ .../parsers/parsetiledjson/ParseTileLayers.js | 104 ++++++ .../parsers/parsetiledjson/ParseTilesets.js | 81 +++++ .../tilemap/parsers/parsetiledjson/index.js | 329 +----------------- 7 files changed, 376 insertions(+), 313 deletions(-) create mode 100644 v3/src/gameobjects/tilemap/parsers/parsetiledjson/AssignTileProperties.js create mode 100644 v3/src/gameobjects/tilemap/parsers/parsetiledjson/BuildTilesetIndex.js create mode 100644 v3/src/gameobjects/tilemap/parsers/parsetiledjson/ParseImageLayers.js create mode 100644 v3/src/gameobjects/tilemap/parsers/parsetiledjson/ParseObjectLayers.js create mode 100644 v3/src/gameobjects/tilemap/parsers/parsetiledjson/ParseTileLayers.js create mode 100644 v3/src/gameobjects/tilemap/parsers/parsetiledjson/ParseTilesets.js diff --git a/v3/src/gameobjects/tilemap/parsers/parsetiledjson/AssignTileProperties.js b/v3/src/gameobjects/tilemap/parsers/parsetiledjson/AssignTileProperties.js new file mode 100644 index 000000000..1eb077f34 --- /dev/null +++ b/v3/src/gameobjects/tilemap/parsers/parsetiledjson/AssignTileProperties.js @@ -0,0 +1,54 @@ +var Extend = require('../../../../utils/object/Extend'); + +// Copy properties from tileset to tiles +var AssignTileProperties = function (mapData) +{ + var layerData; + var tile; + var sid; + var set; + var row; + + // go through each of the map data layers + for (var i = 0; i < mapData.layers.length; i++) + { + layerData = mapData.layers[i]; + + set = null; + + // rows of tiles + for (var j = 0; j < layerData.data.length; j++) + { + row = layerData.data[j]; + + // individual tiles + for (var k = 0; k < row.length; k++) + { + tile = row[k]; + + if (tile === null || tile.index < 0) + { + continue; + } + + // find the relevant tileset + sid = mapData.tiles[tile.index][2]; + set = mapData.tilesets[sid]; + + // Ensure that a tile's size matches its tileset + tile.width = set.tileWidth; + tile.height = set.tileHeight; + + // if that tile type has any properties, add them to the tile object + if (set.tileProperties && set.tileProperties[tile.index - set.firstgid]) + { + tile.properties = Extend( + tile.properties, set.tileProperties[tile.index - set.firstgid] + ); + } + } + } + } +}; + +module.exports = AssignTileProperties; diff --git a/v3/src/gameobjects/tilemap/parsers/parsetiledjson/BuildTilesetIndex.js b/v3/src/gameobjects/tilemap/parsers/parsetiledjson/BuildTilesetIndex.js new file mode 100644 index 000000000..bd8a9de1e --- /dev/null +++ b/v3/src/gameobjects/tilemap/parsers/parsetiledjson/BuildTilesetIndex.js @@ -0,0 +1,52 @@ +// Master list of tiles -> x, y, index in tileset +var BuildTilesetIndex = function (mapData) +{ + var tiles = []; + + for (var i = 0; i < mapData.tilesets.length; i++) + { + var set = mapData.tilesets[i]; + + var x = set.tileMargin; + var y = set.tileMargin; + + var count = 0; + var countX = 0; + var countY = 0; + + for (var t = set.firstgid; t < set.firstgid + set.total; t++) + { + // Can add extra properties here as needed + tiles[t] = [ x, y, i ]; + + x += set.tileWidth + set.tileSpacing; + + count++; + + if (count === set.total) + { + break; + } + + countX++; + + if (countX === set.columns) + { + x = set.tileMargin; + y += set.tileHeight + set.tileSpacing; + + countX = 0; + countY++; + + if (countY === set.rows) + { + break; + } + } + } + } + + return tiles; +}; + +module.exports = BuildTilesetIndex; diff --git a/v3/src/gameobjects/tilemap/parsers/parsetiledjson/ParseImageLayers.js b/v3/src/gameobjects/tilemap/parsers/parsetiledjson/ParseImageLayers.js new file mode 100644 index 000000000..1fb2be099 --- /dev/null +++ b/v3/src/gameobjects/tilemap/parsers/parsetiledjson/ParseImageLayers.js @@ -0,0 +1,30 @@ +var GetFastValue = require('../../../../utils/object/GetFastValue'); + +var ParseImageLayers = function (json) +{ + var images = []; + + for (var i = 0; i < json.layers.length; i++) + { + if (json.layers[i].type !== 'imagelayer') + { + continue; + } + + var curi = json.layers[i]; + + images.push({ + name: curi.name, + image: curi.image, + x: GetFastValue(curi, 'offsetx', 0) + curi.x, + y: GetFastValue(curi, 'offsety', 0) + curi.y, + alpha: curi.opacity, + visible: curi.visible, + properties: GetFastValue(curi, 'properties', {}) + }); + } + + return images; +}; + +module.exports = ParseImageLayers; diff --git a/v3/src/gameobjects/tilemap/parsers/parsetiledjson/ParseObjectLayers.js b/v3/src/gameobjects/tilemap/parsers/parsetiledjson/ParseObjectLayers.js new file mode 100644 index 000000000..45efa5f86 --- /dev/null +++ b/v3/src/gameobjects/tilemap/parsers/parsetiledjson/ParseObjectLayers.js @@ -0,0 +1,39 @@ +var GetFastValue = require('../../../../utils/object/GetFastValue'); +var ParseObject = require('./ParseObject'); + +// Objects & Collision Data (polylines, etc) +var ParseTilesets = function (json) +{ + var objects = {}; + var collision = {}; + + for (var i = 0; i < json.layers.length; i++) + { + if (json.layers[i].type !== 'objectgroup') + { + continue; + } + + var curo = json.layers[i]; + var layerName = curo.name; + var offsetX = GetFastValue(curo, 'offsetx', 0); + var offsetY = GetFastValue(curo, 'offsety', 0); + + objects[layerName] = []; + collision[layerName] = []; + + for (var j = 0; j < curo.objects.length; j++) + { + var parsedObject = ParseObject(curo.objects[j], offsetX, offsetY); + + // Matching v2 where only polylines were added to collision prop of the map + if (parsedObject.polyline) { collision[layerName].push(parsedObject); } + + objects[layerName].push(parsedObject); + } + } + + return { objects: objects, collision: collision }; +}; + +module.exports = ParseTilesets; diff --git a/v3/src/gameobjects/tilemap/parsers/parsetiledjson/ParseTileLayers.js b/v3/src/gameobjects/tilemap/parsers/parsetiledjson/ParseTileLayers.js new file mode 100644 index 000000000..0ec7872d4 --- /dev/null +++ b/v3/src/gameobjects/tilemap/parsers/parsetiledjson/ParseTileLayers.js @@ -0,0 +1,104 @@ +var Base64Decode = require('./Base64Decode'); +var GetFastValue = require('../../../../utils/object/GetFastValue'); +var LayerData = require('../../mapdata/LayerData'); +var ParseGID = require('./ParseGID'); +var Tile = require('../../Tile'); + +var ParseTileLayers = function (json, insertNull) +{ + var tileLayers = []; + + for (var i = 0; i < json.layers.length; i++) + { + if (json.layers[i].type !== 'tilelayer') + { + continue; + } + + var curl = json.layers[i]; + + // Base64 decode data if necessary. NOTE: uncompressed base64 only. + if (curl.compression) + { + console.warn( + 'TilemapParser.parseTiledJSON - Layer compression is unsupported, skipping layer \'' + + curl.name + '\'' + ); + continue; + } + else if (curl.encoding && curl.encoding === 'base64') + { + curl.data = Base64Decode(curl.data); + delete curl.encoding; // Allow the same map to be parsed multiple times + } + + var layerData = new LayerData({ + name: curl.name, + x: GetFastValue(curl, 'offsetx', 0) + curl.x, + y: GetFastValue(curl, 'offsety', 0) + curl.y, + width: curl.width, + height: curl.height, + tileWidth: json.tilewidth, + tileHeight: json.tileheight, + alpha: curl.opacity, + visible: curl.visible, + properties: GetFastValue(curl, 'properties', {}) + }); + + var x = 0; + var row = []; + var output = []; + + // Loop through the data field in the JSON. + + // This is an array containing the tile indexes, one after the other. -1 = no tile, + // everything else = the tile index (starting at 1 for Tiled, 0 for CSV) If the map + // contains multiple tilesets then the indexes are relative to that which the set starts + // from. Need to set which tileset in the cache = which tileset in the JSON, if you do this + // manually it means you can use the same map data but a new tileset. + + for (var t = 0, len = curl.data.length; t < len; t++) + { + var gidInfo = ParseGID(curl.data[t]); + + // index, x, y, width, height + if (gidInfo.gid > 0) + { + var tile = new Tile(layerData, gidInfo.gid, x, output.length, json.tilewidth, + json.tileheight); + + tile.rotation = gidInfo.rotation; + tile.flipped = gidInfo.flipped; + tile.flippedHorizontal = gidInfo.flippedHorizontal; + tile.flippedVertical = gidInfo.flippedVertical; + tile.flippedAntiDiagonal = gidInfo.flippedAntiDiagonal; + + row.push(tile); + } + else + { + var blankTile = insertNull + ? null + : new Tile(layerData, -1, x, output.length, json.tilewidth, json.tileheight); + row.push(blankTile); + } + + x++; + + if (x === curl.width) + { + output.push(row); + x = 0; + row = []; + } + } + + layerData.data = output; + + tileLayers.push(layerData); + } + + return tileLayers; +}; + +module.exports = ParseTileLayers; diff --git a/v3/src/gameobjects/tilemap/parsers/parsetiledjson/ParseTilesets.js b/v3/src/gameobjects/tilemap/parsers/parsetiledjson/ParseTilesets.js new file mode 100644 index 000000000..482a9d30c --- /dev/null +++ b/v3/src/gameobjects/tilemap/parsers/parsetiledjson/ParseTilesets.js @@ -0,0 +1,81 @@ +var Tileset = require('../../Tileset'); +var ImageCollection = require('../../ImageCollection'); +var ParseObject = require('./ParseObject'); + +// Tilesets & Image Collections +var ParseTilesets = function (json) +{ + var tilesets = []; + var imageCollections = []; + var lastSet = null; + var stringID; + + for (var i = 0; i < json.tilesets.length; i++) + { + // name, firstgid, width, height, margin, spacing, properties + var set = json.tilesets[i]; + + if (set.source) + { + console.warn('Phaser can\'t load external tilesets. Use the Embed Tileset button and then export the map again.'); + } + else if (set.image) + { + var newSet = new Tileset(set.name, set.firstgid, set.tilewidth, set.tileheight, set.margin, set.spacing); + + // Properties stored per-tile in object with string indexes starting at "0" + if (set.tileproperties) + { + newSet.tileProperties = set.tileproperties; + } + + // Object & terrain shapes stored per-tile in object with string indexes starting at "0" + if (set.tiles) + { + newSet.tileData = set.tiles; + + // Parse the objects into Phaser format to match handling of other Tiled objects + for (stringID in newSet.tileData) + { + var objectGroup = newSet.tileData[stringID].objectgroup; + if (objectGroup && objectGroup.objects) + { + objectGroup.objects = objectGroup.objects.map(ParseObject); + } + } + } + + // For a normal sliced tileset the row/count/size information is computed when updated. + // This is done (again) after the image is set. + newSet.updateTileData(set.imagewidth, set.imageheight); + + tilesets.push(newSet); + } + else + { + var newCollection = new ImageCollection(set.name, set.firstgid, set.tilewidth, + set.tileheight, set.margin, set.spacing, set.properties); + + for (stringID in set.tiles) + { + var image = set.tiles[stringID].image; + var gid = set.firstgid + parseInt(stringID, 10); + newCollection.addImage(gid, image); + } + + imageCollections.push(newCollection); + } + + // We've got a new Tileset, so set the lastgid into the previous one + if (lastSet) + { + lastSet.lastgid = set.firstgid - 1; + } + + lastSet = set; + } + + return { tilesets: tilesets, imageCollections: imageCollections }; +}; + +module.exports = ParseTilesets; diff --git a/v3/src/gameobjects/tilemap/parsers/parsetiledjson/index.js b/v3/src/gameobjects/tilemap/parsers/parsetiledjson/index.js index 51dd6d4d2..0ca29f5ad 100644 --- a/v3/src/gameobjects/tilemap/parsers/parsetiledjson/index.js +++ b/v3/src/gameobjects/tilemap/parsers/parsetiledjson/index.js @@ -1,14 +1,11 @@ var Formats = require('../../Formats'); -var Tileset = require('../../Tileset'); -var Tile = require('../../Tile'); -var Extend = require('../../../../utils/object/Extend'); var MapData = require('../../mapdata/MapData'); -var LayerData = require('../../mapdata/LayerData'); -var ImageCollection = require('../../ImageCollection'); -var GetFastValue = require('../../../../utils/object/GetFastValue'); -var ParseGID = require('./ParseGID'); -var Base64Decode = require('./Base64Decode'); -var ParseObject = require('./ParseObject'); +var ParseTileLayers = require('./ParseTileLayers'); +var ParseImageLayers = require('./ParseImageLayers'); +var ParseTilesets = require('./ParseTilesets'); +var ParseObjectLayers = require('./ParseObjectLayers'); +var BuildTilesetIndex = require('./BuildTilesetIndex'); +var AssignTileProperties = require('./AssignTileProperties'); /** * Parses a Tiled JSON object into a new MapData object. @@ -43,315 +40,21 @@ var ParseJSONTiled = function (name, json, insertNull) properties: json.properties }); - var tileLayers = []; + mapData.layers = ParseTileLayers(json, insertNull); + mapData.images = ParseImageLayers(json); - for (var i = 0; i < json.layers.length; i++) - { - if (json.layers[i].type !== 'tilelayer') - { - continue; - } + var sets = ParseTilesets(json); + mapData.tilesets = sets.tilesets; + mapData.imageCollections = sets.imageCollections; - var curl = json.layers[i]; + var objs = ParseObjectLayers(json); + mapData.objects = objs.objects; + mapData.collision = objs.collision; - // Base64 decode data if necessary. NOTE: uncompressed base64 only. - if (curl.compression) - { - console.warn('TilemapParser.parseTiledJSON - Layer compression is unsupported, skipping layer \'' + curl.name + '\''); - continue; - } - else if (curl.encoding && curl.encoding === 'base64') - { - curl.data = Base64Decode(curl.data); - } + mapData.tiles = BuildTilesetIndex(mapData); - var layerData = new LayerData({ - name: curl.name, - x: GetFastValue(curl, 'offsetx', 0) + curl.x, - y: GetFastValue(curl, 'offsety', 0) + curl.y, - width: curl.width, - height: curl.height, - tileWidth: json.tilewidth, - tileHeight: json.tileheight, - alpha: curl.opacity, - visible: curl.visible, - properties: GetFastValue(curl, 'properties', {}) - }); + AssignTileProperties(mapData); - var x = 0; - var row = []; - var output = []; - var gid; - - // Loop through the data field in the JSON. - - // This is an array containing the tile indexes, one after the other. -1 = no tile, - // everything else = the tile index (starting at 1 for Tiled, 0 for CSV) If the map - // contains multiple tilesets then the indexes are relative to that which the set starts - // from. Need to set which tileset in the cache = which tileset in the JSON, if you do this - // manually it means you can use the same map data but a new tileset. - - for (var t = 0, len = curl.data.length; t < len; t++) - { - var gidInfo = ParseGID(curl.data[t]); - - // index, x, y, width, height - if (gidInfo.gid > 0) - { - var tile = new Tile(layerData, gidInfo.gid, x, output.length, json.tilewidth, json.tileheight); - - tile.rotation = gidInfo.rotation; - tile.flipped = gidInfo.flipped; - tile.flippedHorizontal = gidInfo.flippedHorizontal; - tile.flippedVertical = gidInfo.flippedVertical; - tile.flippedAntiDiagonal = gidInfo.flippedAntiDiagonal; - - row.push(tile); - } - else - { - var blankTile = insertNull - ? null - : new Tile(layerData, -1, x, output.length, json.tilewidth, json.tileheight); - row.push(blankTile); - } - - x++; - - if (x === curl.width) - { - output.push(row); - x = 0; - row = []; - } - } - - layerData.data = output; - - tileLayers.push(layerData); - } - - mapData.layers = tileLayers; - - var images = []; - - for (var i = 0; i < json.layers.length; i++) - { - if (json.layers[i].type !== 'imagelayer') - { - continue; - } - - var curi = json.layers[i]; - - images.push({ - name: curi.name, - image: curi.image, - x: GetFastValue(curi, 'offsetx', 0) + curi.x, - y: GetFastValue(curi, 'offsety', 0) + curi.y, - alpha: curi.opacity, - visible: curi.visible, - properties: GetFastValue(curi, 'properties', {}) - }); - } - - mapData.images = images; - - // Tilesets & Image Collections - var tilesets = []; - var imageCollections = []; - var lastSet = null; - - for (var i = 0; i < json.tilesets.length; i++) - { - // name, firstgid, width, height, margin, spacing, properties - var set = json.tilesets[i]; - - if (set.image) - { - var newSet = new Tileset(set.name, set.firstgid, set.tilewidth, set.tileheight, set.margin, set.spacing); - - // Properties stored per-tile in object with string indexes starting at "0" - if (set.tileproperties) - { - newSet.tileProperties = set.tileproperties; - } - - // Object & terrain shapes stored per-tile in object with string indexes starting at "0" - if (set.tiles) - { - newSet.tileData = set.tiles; - - // Parse the objects into Phaser format to match handling of other Tiled objects - for (var stringID in newSet.tileData) - { - var objectGroup = newSet.tileData[stringID].objectgroup; - if (objectGroup && objectGroup.objects) - { - objectGroup.objects = objectGroup.objects.map(ParseObject); - } - } - } - - // For a normal sliced tileset the row/count/size information is computed when updated. - // This is done (again) after the image is set. - newSet.updateTileData(set.imagewidth, set.imageheight); - - tilesets.push(newSet); - } - else - { - var newCollection = new ImageCollection(set.name, set.firstgid, set.tilewidth, set.tileheight, set.margin, set.spacing, set.properties); - - for (var stringID in set.tiles) - { - var image = set.tiles[stringID].image; - var gid = set.firstgid + parseInt(stringID, 10); - newCollection.addImage(gid, image); - } - - imageCollections.push(newCollection); - } - - // We've got a new Tileset, so set the lastgid into the previous one - if (lastSet) - { - lastSet.lastgid = set.firstgid - 1; - } - - lastSet = set; - } - - mapData.tilesets = tilesets; - mapData.imageCollections = imageCollections; - - // Objects & Collision Data (polylines, etc) - var objects = {}; - var collision = {}; - - for (var i = 0; i < json.layers.length; i++) - { - if (json.layers[i].type !== 'objectgroup') - { - continue; - } - - var curo = json.layers[i]; - var layerName = curo.name; - var offsetX = GetFastValue(curo, 'offsetx', 0); - var offsetY = GetFastValue(curo, 'offsety', 0); - - objects[layerName] = []; - collision[layerName] = []; - - for (var j = 0; j < curo.objects.length; j++) - { - var parsedObject = ParseObject(curo.objects[j], offsetX, offsetY); - - // Matching v2 where only polylines were added to collision prop of the map - if (parsedObject.polyline) { collision[layerName].push(parsedObject); } - - objects[layerName].push(parsedObject); - } - } - - mapData.objects = objects; - mapData.collision = collision; - - mapData.tiles = []; - - // Finally lets build our super tileset index - for (var i = 0; i < mapData.tilesets.length; i++) - { - var set = mapData.tilesets[i]; - - var x = set.tileMargin; - var y = set.tileMargin; - - var count = 0; - var countX = 0; - var countY = 0; - - for (var t = set.firstgid; t < set.firstgid + set.total; t++) - { - // Can add extra properties here as needed - mapData.tiles[t] = [ x, y, i ]; - - x += set.tileWidth + set.tileSpacing; - - count++; - - if (count === set.total) - { - break; - } - - countX++; - - if (countX === set.columns) - { - x = set.tileMargin; - y += set.tileHeight + set.tileSpacing; - - countX = 0; - countY++; - - if (countY === set.rows) - { - break; - } - } - } - - } - - // assign tile properties - - var layerData; - var tile; - var sid; - var set; - - // go through each of the map data layers - for (var i = 0; i < mapData.layers.length; i++) - { - layerData = mapData.layers[i]; - - set = null; - - // rows of tiles - for (var j = 0; j < layerData.data.length; j++) - { - row = layerData.data[j]; - - // individual tiles - for (var k = 0; k < row.length; k++) - { - tile = row[k]; - - if (tile === null || tile.index < 0) - { - continue; - } - - // find the relevant tileset - - sid = mapData.tiles[tile.index][2]; - set = mapData.tilesets[sid]; - - // Ensure that a tile's size matches its tileset - tile.width = set.tileWidth; - tile.height = set.tileHeight; - - // if that tile type has any properties, add them to the tile object - if (set.tileProperties && set.tileProperties[tile.index - set.firstgid]) - { - tile.properties = Extend(tile.properties, set.tileProperties[tile.index - set.firstgid]); - } - - } - } - } return mapData; };