mirror of
https://github.com/photonstorm/phaser
synced 2024-11-26 22:52:14 +00:00
Support for Tiled Groups and Infinite Map Fixes
- Added support for Tiled group layers (issue #4099) - Fixed some layer offset bugs for infinite maps
This commit is contained in:
parent
c25331cf30
commit
a9e897370a
4 changed files with 221 additions and 38 deletions
55
src/tilemaps/parsers/tiled/CreateGroupLayer.js
Normal file
55
src/tilemaps/parsers/tiled/CreateGroupLayer.js
Normal file
|
@ -0,0 +1,55 @@
|
|||
/**
|
||||
* @author Seth Berrier <berriers@uwstout.edu>
|
||||
* @copyright 2019 Photon Storm Ltd.
|
||||
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
||||
*/
|
||||
|
||||
var GetFastValue = require('../../../utils/object/GetFastValue');
|
||||
|
||||
/**
|
||||
* Parse a Tiled group layer and create a state object for inheriting.
|
||||
*
|
||||
* @function Phaser.Tilemaps.Parsers.Tiled.CreateGroupLayer
|
||||
* @since 3.21.0
|
||||
*
|
||||
* @param {object} json - The Tiled JSON object.
|
||||
* @param {object} [currentl] - The current group layer from the Tiled JSON file.
|
||||
* @param {object} [parentstate] - The state of the parent group (if any).
|
||||
*
|
||||
* @return {object} A group state object with proper values for updating children layers.
|
||||
*/
|
||||
var CreateGroupLayer = function (json, groupl, parentstate)
|
||||
{
|
||||
if (!groupl)
|
||||
{
|
||||
// Return a default group state object
|
||||
return {
|
||||
i: 0, // Current layer array iterator
|
||||
layers: json.layers, // Current array of layers
|
||||
|
||||
// Values inherited from parent group
|
||||
name: '',
|
||||
opacity: 1,
|
||||
visible: true,
|
||||
x: 0,
|
||||
y: 0
|
||||
};
|
||||
}
|
||||
|
||||
// Compute group layer x, y
|
||||
var layerX = groupl.x + GetFastValue(groupl, 'startx', 0) * json.tilewidth + GetFastValue(groupl, 'offsetx', 0);
|
||||
var layerY = groupl.y + GetFastValue(groupl, 'starty', 0) * json.tileheight + GetFastValue(groupl, 'offsety', 0);
|
||||
|
||||
// Compute next state inherited from group
|
||||
return {
|
||||
i: 0,
|
||||
layers: groupl.layers,
|
||||
name: parentstate.name + groupl.name + '/',
|
||||
opacity: parentstate.opacity * groupl.opacity,
|
||||
visible: parentstate.visible && groupl.visible,
|
||||
x: parentstate.x + layerX,
|
||||
y: parentstate.y + layerY
|
||||
};
|
||||
};
|
||||
|
||||
module.exports = CreateGroupLayer;
|
|
@ -5,37 +5,73 @@
|
|||
*/
|
||||
|
||||
var GetFastValue = require('../../../utils/object/GetFastValue');
|
||||
var CreateGroupLayer = require('./CreateGroupLayer');
|
||||
|
||||
/**
|
||||
* [description]
|
||||
* Parses a Tiled JSON object into an array of objects with details about the image layers.
|
||||
*
|
||||
* @function Phaser.Tilemaps.Parsers.Tiled.ParseImageLayers
|
||||
* @since 3.0.0
|
||||
*
|
||||
* @param {object} json - [description]
|
||||
* @param {object} json - The Tiled JSON object.
|
||||
*
|
||||
* @return {array} [description]
|
||||
* @return {array} Array of objects that include critical info about the map's image layers
|
||||
*/
|
||||
var ParseImageLayers = function (json)
|
||||
{
|
||||
var images = [];
|
||||
|
||||
for (var i = 0; i < json.layers.length; i++)
|
||||
// State inherited from a parent group
|
||||
var groupStack = [];
|
||||
var curGroupState = CreateGroupLayer(json);
|
||||
|
||||
while (curGroupState.i < curGroupState.layers.length || groupStack.length > 0)
|
||||
{
|
||||
if (json.layers[i].type !== 'imagelayer')
|
||||
if (curGroupState.i >= curGroupState.layers.length)
|
||||
{
|
||||
// Ensure recursion stack is not empty first
|
||||
if (groupStack.length < 1)
|
||||
{
|
||||
console.warn(
|
||||
'TilemapParser.parseTiledJSON - Invalid layer group hierarchy'
|
||||
);
|
||||
break;
|
||||
}
|
||||
|
||||
// Return to previous recursive state
|
||||
curGroupState = groupStack.pop();
|
||||
continue;
|
||||
}
|
||||
|
||||
var curi = json.layers[i];
|
||||
// Get current layer and advance iterator
|
||||
var curi = curGroupState.layers[curGroupState.i];
|
||||
curGroupState.i++;
|
||||
|
||||
if (curi.type !== 'imagelayer')
|
||||
{
|
||||
if (curi.type === 'group')
|
||||
{
|
||||
// Compute next state inherited from group
|
||||
var nextGroupState = CreateGroupLayer(json, curi, curGroupState);
|
||||
|
||||
// Preserve current state before recursing
|
||||
groupStack.push(curGroupState);
|
||||
curGroupState = nextGroupState;
|
||||
}
|
||||
|
||||
// Skip this layer OR 'recurse' (iterative style) into the group
|
||||
continue;
|
||||
}
|
||||
|
||||
var layerOffsetX = GetFastValue(curi, 'offsetx', 0) + GetFastValue(curi, 'startx', 0);
|
||||
var layerOffsetY = GetFastValue(curi, 'offsety', 0) + GetFastValue(curi, 'starty', 0);
|
||||
images.push({
|
||||
name: curi.name,
|
||||
name: (curGroupState.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,
|
||||
x: (curGroupState.x + layerOffsetX + curi.x),
|
||||
y: (curGroupState.y + layerOffsetY + curi.y),
|
||||
alpha: (curGroupState.opacity * curi.opacity),
|
||||
visible: (curGroupState.visible && curi.visible),
|
||||
properties: GetFastValue(curi, 'properties', {})
|
||||
});
|
||||
}
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
var GetFastValue = require('../../../utils/object/GetFastValue');
|
||||
var ParseObject = require('./ParseObject');
|
||||
var ObjectLayer = require('../../mapdata/ObjectLayer');
|
||||
var CreateGroupLayer = require('./CreateGroupLayer');
|
||||
|
||||
/**
|
||||
* Parses a Tiled JSON object into an array of ObjectLayer objects.
|
||||
|
@ -22,18 +23,57 @@ var ParseObjectLayers = function (json)
|
|||
{
|
||||
var objectLayers = [];
|
||||
|
||||
for (var i = 0; i < json.layers.length; i++)
|
||||
// State inherited from a parent group
|
||||
var groupStack = [];
|
||||
var curGroupState = CreateGroupLayer(json);
|
||||
|
||||
while (curGroupState.i < curGroupState.layers.length || groupStack.length > 0)
|
||||
{
|
||||
if (json.layers[i].type !== 'objectgroup')
|
||||
if (curGroupState.i >= curGroupState.layers.length)
|
||||
{
|
||||
// Ensure recursion stack is not empty first
|
||||
if (groupStack.length < 1)
|
||||
{
|
||||
console.warn(
|
||||
'TilemapParser.parseTiledJSON - Invalid layer group hierarchy'
|
||||
);
|
||||
break;
|
||||
}
|
||||
|
||||
// Return to previous recursive state
|
||||
curGroupState = groupStack.pop();
|
||||
continue;
|
||||
}
|
||||
|
||||
var curo = json.layers[i];
|
||||
var offsetX = GetFastValue(curo, 'offsetx', 0);
|
||||
var offsetY = GetFastValue(curo, 'offsety', 0);
|
||||
var objects = [];
|
||||
// Get current layer and advance iterator
|
||||
var curo = curGroupState.layers[curGroupState.i];
|
||||
curGroupState.i++;
|
||||
|
||||
// Modify inherited properties
|
||||
curo.opacity *= curGroupState.opacity;
|
||||
curo.visible = curGroupState.visible && curo.visible;
|
||||
|
||||
if (curo.type !== 'objectgroup')
|
||||
{
|
||||
if (curo.type === 'group')
|
||||
{
|
||||
// Compute next state inherited from group
|
||||
var nextGroupState = CreateGroupLayer(json, curo, curGroupState);
|
||||
|
||||
// Preserve current state before recursing
|
||||
groupStack.push(curGroupState);
|
||||
curGroupState = nextGroupState;
|
||||
}
|
||||
|
||||
// Skip this layer OR 'recurse' (iterative style) into the group
|
||||
continue;
|
||||
}
|
||||
|
||||
curo.name = curGroupState.name + curo.name;
|
||||
var offsetX = curGroupState.x + GetFastValue(curo, 'startx', 0) + GetFastValue(curo, 'offsetx', 0);
|
||||
var offsetY = curGroupState.y + GetFastValue(curo, 'starty', 0) + GetFastValue(curo, 'offsety', 0);
|
||||
|
||||
var objects = [];
|
||||
for (var j = 0; j < curo.objects.length; j++)
|
||||
{
|
||||
var parsedObject = ParseObject(curo.objects[j], offsetX, offsetY);
|
||||
|
|
|
@ -9,31 +9,66 @@ var GetFastValue = require('../../../utils/object/GetFastValue');
|
|||
var LayerData = require('../../mapdata/LayerData');
|
||||
var ParseGID = require('./ParseGID');
|
||||
var Tile = require('../../Tile');
|
||||
var CreateGroupLayer = require('./CreateGroupLayer');
|
||||
|
||||
/**
|
||||
* [description]
|
||||
* Parses all tilemap layers in a Tiled JSON object into new LayerData objects.
|
||||
*
|
||||
* @function Phaser.Tilemaps.Parsers.Tiled.ParseTileLayers
|
||||
* @since 3.0.0
|
||||
*
|
||||
* @param {object} json - [description]
|
||||
* @param {boolean} insertNull - [description]
|
||||
* @param {object} json - The Tiled JSON object.
|
||||
* @param {boolean} insertNull - Controls how empty tiles, tiles with an index of -1, in the map
|
||||
* data are handled (see {@link Phaser.Tilemaps.Parsers.Tiled.ParseJSONTiled}).
|
||||
*
|
||||
* @return {array} [description]
|
||||
* @return {Phaser.Tilemaps.LayerData[]} - An array of LayerData objects, one for each entry in
|
||||
* json.layers with the type 'tilelayer'.
|
||||
*/
|
||||
var ParseTileLayers = function (json, insertNull)
|
||||
{
|
||||
var infiniteMap = GetFastValue(json, 'infinite', false);
|
||||
var tileLayers = [];
|
||||
|
||||
for (var i = 0; i < json.layers.length; i++)
|
||||
// State inherited from a parent group
|
||||
var groupStack = [];
|
||||
var curGroupState = CreateGroupLayer(json);
|
||||
|
||||
while (curGroupState.i < curGroupState.layers.length || groupStack.length > 0)
|
||||
{
|
||||
if (json.layers[i].type !== 'tilelayer')
|
||||
if (curGroupState.i >= curGroupState.layers.length)
|
||||
{
|
||||
// Ensure recursion stack is not empty first
|
||||
if (groupStack.length < 1)
|
||||
{
|
||||
console.warn(
|
||||
'TilemapParser.parseTiledJSON - Invalid layer group hierarchy'
|
||||
);
|
||||
break;
|
||||
}
|
||||
|
||||
// Return to previous recursive state
|
||||
curGroupState = groupStack.pop();
|
||||
continue;
|
||||
}
|
||||
|
||||
var curl = json.layers[i];
|
||||
var curl = curGroupState.layers[curGroupState.i];
|
||||
curGroupState.i++;
|
||||
|
||||
if (curl.type !== 'tilelayer')
|
||||
{
|
||||
if (curl.type === 'group')
|
||||
{
|
||||
// Compute next state inherited from group
|
||||
var nextGroupState = CreateGroupLayer(json, curl, curGroupState);
|
||||
|
||||
// Preserve current state before recursing
|
||||
groupStack.push(curGroupState);
|
||||
curGroupState = nextGroupState;
|
||||
}
|
||||
|
||||
// Skip this layer OR 'recurse' (iterative style) into the group
|
||||
continue;
|
||||
}
|
||||
|
||||
// Base64 decode data if necessary. NOTE: uncompressed base64 only.
|
||||
if (curl.compression)
|
||||
|
@ -46,7 +81,21 @@ var ParseTileLayers = function (json, insertNull)
|
|||
}
|
||||
else if (curl.encoding && curl.encoding === 'base64')
|
||||
{
|
||||
curl.data = Base64Decode(curl.data);
|
||||
// Chunks for an infinite map
|
||||
if (curl.chunks)
|
||||
{
|
||||
for (var i = 0; i < curl.chunks.length; i++)
|
||||
{
|
||||
curl.chunks[i].data = Base64Decode(curl.chunks[i].data);
|
||||
}
|
||||
}
|
||||
|
||||
// Non-infinite map data
|
||||
if (curl.data)
|
||||
{
|
||||
curl.data = Base64Decode(curl.data);
|
||||
}
|
||||
|
||||
delete curl.encoding; // Allow the same map to be parsed multiple times
|
||||
}
|
||||
|
||||
|
@ -66,18 +115,18 @@ var ParseTileLayers = function (json, insertNull)
|
|||
|
||||
if (infiniteMap)
|
||||
{
|
||||
var layerOffsetX = GetFastValue(curl, 'startx', 0) + curl.x;
|
||||
var layerOffsetY = GetFastValue(curl, 'starty', 0) + curl.y;
|
||||
var layerOffsetX = (GetFastValue(curl, 'startx', 0) + curl.x);
|
||||
var layerOffsetY = (GetFastValue(curl, 'starty', 0) + curl.y);
|
||||
layerData = new LayerData({
|
||||
name: curl.name,
|
||||
x: layerOffsetX,
|
||||
y: layerOffsetY,
|
||||
name: (curGroupState.name + curl.name),
|
||||
x: (curGroupState.x + GetFastValue(curl, 'offsetx', 0) + layerOffsetX * json.tilewidth),
|
||||
y: (curGroupState.y + GetFastValue(curl, 'offsety', 0) + layerOffsetY * json.tileheight),
|
||||
width: curl.width,
|
||||
height: curl.height,
|
||||
tileWidth: json.tilewidth,
|
||||
tileHeight: json.tileheight,
|
||||
alpha: curl.opacity,
|
||||
visible: curl.visible,
|
||||
alpha: (curGroupState.opacity * curl.opacity),
|
||||
visible: (curGroupState.visible && curl.visible),
|
||||
properties: GetFastValue(curl, 'properties', {})
|
||||
});
|
||||
|
||||
|
@ -142,15 +191,15 @@ var ParseTileLayers = function (json, insertNull)
|
|||
else
|
||||
{
|
||||
layerData = new LayerData({
|
||||
name: curl.name,
|
||||
x: GetFastValue(curl, 'offsetx', 0) + curl.x,
|
||||
y: GetFastValue(curl, 'offsety', 0) + curl.y,
|
||||
name: (curGroupState.name + curl.name),
|
||||
x: (curGroupState.x + GetFastValue(curl, 'offsetx', 0) + curl.x),
|
||||
y: (curGroupState.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,
|
||||
alpha: (curGroupState.opacity * curl.opacity),
|
||||
visible: (curGroupState.visible && curl.visible),
|
||||
properties: GetFastValue(curl, 'properties', {})
|
||||
});
|
||||
|
||||
|
@ -194,10 +243,13 @@ var ParseTileLayers = function (json, insertNull)
|
|||
}
|
||||
|
||||
layerData.data = output;
|
||||
|
||||
tileLayers.push(layerData);
|
||||
}
|
||||
|
||||
tileLayers.forEach(function (curLayer)
|
||||
{
|
||||
console.warn(`${curLayer.name} - (${curLayer.x}, ${curLayer.y}) [${curLayer.alpha} / ${curLayer.visible}]`);
|
||||
});
|
||||
return tileLayers;
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in a new issue