From 9b6be3466b7065bfff8556e91d2f44690c458acd Mon Sep 17 00:00:00 2001 From: Lurkars Date: Sat, 27 Feb 2021 15:23:57 +0100 Subject: [PATCH 1/5] support for group layer of Tiled (excludes 'start' layer) --- front/src/Phaser/Game/GameMap.ts | 18 +++++++++--- front/src/Phaser/Game/GameScene.ts | 45 ++++++++++++++++++------------ front/src/Phaser/Map/ITiledMap.ts | 5 ++++ 3 files changed, 46 insertions(+), 22 deletions(-) diff --git a/front/src/Phaser/Game/GameMap.ts b/front/src/Phaser/Game/GameMap.ts index 110a29d6..c6d58eb2 100644 --- a/front/src/Phaser/Game/GameMap.ts +++ b/front/src/Phaser/Game/GameMap.ts @@ -1,4 +1,4 @@ -import {ITiledMap} from "../Map/ITiledMap"; +import {ITiledMap, ITiledMapLayer} from "../Map/ITiledMap"; export type PropertyChangeCallback = (newValue: string | number | boolean | undefined, oldValue: string | number | boolean | undefined, allProps: Map) => void; @@ -52,10 +52,15 @@ export class GameMap { return this.lastProperties; } - private getProperties(key: number): Map { - const properties = new Map(); + // helper for recursive group layer support + private getPropertiesHelper(key: number, layers: ITiledMapLayer[], properties: Map): Map { + + for (const layer of layers) { + if (layer.type === 'group') { + this.getPropertiesHelper(key, layer.layers, properties); + continue; + } - for (const layer of this.map.layers) { if (layer.type !== 'tilelayer') { continue; } @@ -77,6 +82,11 @@ export class GameMap { return properties; } + private getProperties(key: number): Map { + const properties = new Map(); + return this.getPropertiesHelper(key, this.map.layers, properties); + } + private trigger(propName: string, oldValue: string | number | boolean | undefined, newValue: string | number | boolean | undefined, allProps: Map) { const callbacksArray = this.callbacks.get(propName); if (callbacksArray !== undefined) { diff --git a/front/src/Phaser/Game/GameScene.ts b/front/src/Phaser/Game/GameScene.ts index 144890a3..84b99a7d 100644 --- a/front/src/Phaser/Game/GameScene.ts +++ b/front/src/Phaser/Game/GameScene.ts @@ -353,6 +353,31 @@ export class GameScene extends ResizableScene implements CenterListener { } } + // helper for recursive group layer support + private createHelper(that: this, layers: ITiledMapLayer[], depth: integer, prefix: string): integer { + for(const layer of layers) { + if(layer.type === 'tilelayer') { + that.addLayer(that.Map.createStaticLayer(prefix + layer.name, that.Terrains, 0, 0).setDepth(depth)); + + const exitSceneUrl = that.getExitSceneUrl(layer); + if(exitSceneUrl !== undefined) { + that.loadNextGame(exitSceneUrl); + } + const exitUrl = that.getExitUrl(layer); + if(exitUrl !== undefined) { + that.loadNextGame(exitUrl); + } + } + if(layer.type === 'group') { + that.createHelper(that, layer.layers, depth, prefix + layer.name + '/'); + } + if(layer.type === 'objectgroup' && layer.name === 'floorLayer') { + depth = 10000; + } + } + return depth; + } + //hook create scene create(): void { gameManager.gameSceneIsCreated(this); @@ -386,24 +411,8 @@ export class GameScene extends ResizableScene implements CenterListener { //add layer on map this.Layers = new Array(); - let depth = -2; - for (const layer of this.mapFile.layers) { - if (layer.type === 'tilelayer') { - this.addLayer(this.Map.createStaticLayer(layer.name, this.Terrains, 0, 0).setDepth(depth)); - - const exitSceneUrl = this.getExitSceneUrl(layer); - if (exitSceneUrl !== undefined) { - this.loadNextGame(exitSceneUrl); - } - const exitUrl = this.getExitUrl(layer); - if (exitUrl !== undefined) { - this.loadNextGame(exitUrl); - } - } - if (layer.type === 'objectgroup' && layer.name === 'floorLayer') { - depth = 10000; - } - } + let depth = this.createHelper(this, this.mapFile.layers, -2, ''); + if (depth === -2) { throw new Error('Your map MUST contain a layer of type "objectgroup" whose name is "floorLayer" that represents the layer characters are drawn at.'); } diff --git a/front/src/Phaser/Map/ITiledMap.ts b/front/src/Phaser/Map/ITiledMap.ts index 39e0a1f5..6dfb4a2c 100644 --- a/front/src/Phaser/Map/ITiledMap.ts +++ b/front/src/Phaser/Map/ITiledMap.ts @@ -61,6 +61,11 @@ export interface ITiledMapLayer { */ draworder: string; objects: ITiledMapObject[]; + + /** + * Layers for group layer + */ + layers: this[]; } export interface ITiledMapObject { From 93b7b7bc910064ed4e450c4d12db5e0525109511 Mon Sep 17 00:00:00 2001 From: Lurkars Date: Sat, 27 Feb 2021 15:44:31 +0100 Subject: [PATCH 2/5] removed redundancy, fix for startLayer --- front/src/Phaser/Game/GameScene.ts | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/front/src/Phaser/Game/GameScene.ts b/front/src/Phaser/Game/GameScene.ts index 84b99a7d..4ec5e4ad 100644 --- a/front/src/Phaser/Game/GameScene.ts +++ b/front/src/Phaser/Game/GameScene.ts @@ -354,22 +354,22 @@ export class GameScene extends ResizableScene implements CenterListener { } // helper for recursive group layer support - private createHelper(that: this, layers: ITiledMapLayer[], depth: integer, prefix: string): integer { + private createHelper(layers: ITiledMapLayer[], depth: integer, prefix: string): integer { for(const layer of layers) { if(layer.type === 'tilelayer') { - that.addLayer(that.Map.createStaticLayer(prefix + layer.name, that.Terrains, 0, 0).setDepth(depth)); + this.addLayer(this.Map.createStaticLayer(prefix + layer.name, this.Terrains, 0, 0).setDepth(depth)); - const exitSceneUrl = that.getExitSceneUrl(layer); + const exitSceneUrl = this.getExitSceneUrl(layer); if(exitSceneUrl !== undefined) { - that.loadNextGame(exitSceneUrl); + this.loadNextGame(exitSceneUrl); } - const exitUrl = that.getExitUrl(layer); + const exitUrl = this.getExitUrl(layer); if(exitUrl !== undefined) { - that.loadNextGame(exitUrl); + this.loadNextGame(exitUrl); } } if(layer.type === 'group') { - that.createHelper(that, layer.layers, depth, prefix + layer.name + '/'); + this.createHelper(layer.layers, depth, prefix + layer.name + '/'); } if(layer.type === 'objectgroup' && layer.name === 'floorLayer') { depth = 10000; @@ -411,7 +411,7 @@ export class GameScene extends ResizableScene implements CenterListener { //add layer on map this.Layers = new Array(); - let depth = this.createHelper(this, this.mapFile.layers, -2, ''); + let depth = this.createHelper(this.mapFile.layers, -2, ''); if (depth === -2) { throw new Error('Your map MUST contain a layer of type "objectgroup" whose name is "floorLayer" that represents the layer characters are drawn at.'); @@ -964,16 +964,22 @@ ${escapedMessage} } } - private initPositionFromLayerName(layerName: string) { - for (const layer of this.mapFile.layers) { + private initPositionFromLayerNameHelper(layerName: string, layers : ITiledMapLayer[]) { + for (const layer of layers) { if (layerName === layer.name && layer.type === 'tilelayer' && (layerName === defaultStartLayerName || this.isStartLayer(layer))) { const startPosition = this.startUser(layer); this.startX = startPosition.x + this.mapFile.tilewidth/2; this.startY = startPosition.y + this.mapFile.tileheight/2; + } else if (layer.type === 'group') { + this.initPositionFromLayerNameHelper(layerName, layer.layers); } } } + private initPositionFromLayerName(layerName: string) { + this.initPositionFromLayerNameHelper(layerName, this.mapFile.layers); + } + private getExitUrl(layer: ITiledMapLayer): string|undefined { return this.getProperty(layer, "exitUrl") as string|undefined; } From 66b90be0da2307bdbdfa0bbe75fc1f90f08278e6 Mon Sep 17 00:00:00 2001 From: Lurkars Date: Sat, 27 Feb 2021 15:52:17 +0100 Subject: [PATCH 3/5] remove redundancy --- front/src/Phaser/Game/GameScene.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/front/src/Phaser/Game/GameScene.ts b/front/src/Phaser/Game/GameScene.ts index 4ec5e4ad..e33f1023 100644 --- a/front/src/Phaser/Game/GameScene.ts +++ b/front/src/Phaser/Game/GameScene.ts @@ -411,9 +411,8 @@ export class GameScene extends ResizableScene implements CenterListener { //add layer on map this.Layers = new Array(); - let depth = this.createHelper(this.mapFile.layers, -2, ''); - if (depth === -2) { + if (this.createHelper(this.mapFile.layers, -2, '') === -2) { throw new Error('Your map MUST contain a layer of type "objectgroup" whose name is "floorLayer" that represents the layer characters are drawn at.'); } From 6815fe7a0a965895af888b7465606a398594d70c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20N=C3=A9grier?= Date: Thu, 15 Apr 2021 22:39:35 +0200 Subject: [PATCH 4/5] Added a new LayersIterator class This class iterates recursively over layers, flattening groups. This enables us to simplify the code when we iterate layers. We can remove all recursive function calls in the GameScene code (it is delegated to the LayersIterator) --- front/src/Phaser/Game/GameMap.ts | 19 +-- front/src/Phaser/Game/GameScene.ts | 76 +++++----- front/src/Phaser/Map/ITiledMap.ts | 61 ++++++-- front/src/Phaser/Map/LayersIterator.ts | 44 ++++++ front/tests/Phaser/Map/LayersIteratorTest.ts | 147 +++++++++++++++++++ maps/tests/grouped_map.json | 102 +++++++++++++ 6 files changed, 384 insertions(+), 65 deletions(-) create mode 100644 front/src/Phaser/Map/LayersIterator.ts create mode 100644 front/tests/Phaser/Map/LayersIteratorTest.ts create mode 100644 maps/tests/grouped_map.json diff --git a/front/src/Phaser/Game/GameMap.ts b/front/src/Phaser/Game/GameMap.ts index c6d58eb2..5fe91b62 100644 --- a/front/src/Phaser/Game/GameMap.ts +++ b/front/src/Phaser/Game/GameMap.ts @@ -1,4 +1,5 @@ import {ITiledMap, ITiledMapLayer} from "../Map/ITiledMap"; +import {LayersIterator} from "../Map/LayersIterator"; export type PropertyChangeCallback = (newValue: string | number | boolean | undefined, oldValue: string | number | boolean | undefined, allProps: Map) => void; @@ -10,8 +11,10 @@ export class GameMap { private key: number|undefined; private lastProperties = new Map(); private callbacks = new Map>(); + public readonly layersIterator: LayersIterator; public constructor(private map: ITiledMap) { + this.layersIterator = new LayersIterator(map); } /** @@ -52,15 +55,10 @@ export class GameMap { return this.lastProperties; } - // helper for recursive group layer support - private getPropertiesHelper(key: number, layers: ITiledMapLayer[], properties: Map): Map { - - for (const layer of layers) { - if (layer.type === 'group') { - this.getPropertiesHelper(key, layer.layers, properties); - continue; - } + private getProperties(key: number): Map { + const properties = new Map(); + for (const layer of this.layersIterator) { if (layer.type !== 'tilelayer') { continue; } @@ -82,11 +80,6 @@ export class GameMap { return properties; } - private getProperties(key: number): Map { - const properties = new Map(); - return this.getPropertiesHelper(key, this.map.layers, properties); - } - private trigger(propName: string, oldValue: string | number | boolean | undefined, newValue: string | number | boolean | undefined, allProps: Map) { const callbacksArray = this.callbacks.get(propName); if (callbacksArray !== undefined) { diff --git a/front/src/Phaser/Game/GameScene.ts b/front/src/Phaser/Game/GameScene.ts index e33f1023..806fc32e 100644 --- a/front/src/Phaser/Game/GameScene.ts +++ b/front/src/Phaser/Game/GameScene.ts @@ -18,7 +18,14 @@ import { RESOLUTION, ZOOM_LEVEL } from "../../Enum/EnvironmentVariable"; -import {ITiledMap, ITiledMapLayer, ITiledMapLayerProperty, ITiledMapObject, ITiledTileSet} from "../Map/ITiledMap"; +import { + ITiledMap, + ITiledMapLayer, + ITiledMapLayerProperty, + ITiledMapObject, + ITiledMapTileLayer, + ITiledTileSet +} from "../Map/ITiledMap"; import {AddPlayerInterface} from "./AddPlayerInterface"; import {PlayerAnimationDirections} from "../Player/Animation"; import {PlayerMovement} from "./PlayerMovement"; @@ -77,6 +84,7 @@ import DOMElement = Phaser.GameObjects.DOMElement; import {Subscription} from "rxjs"; import {worldFullMessageStream} from "../../Connexion/WorldFullMessageStream"; import { lazyLoadCompanionResource } from "../Companion/CompanionTexturesLoadingManager"; +import {LayersIterator} from "../Map/LayersIterator"; import {touchScreenManager} from "../../Touch/TouchScreenManager"; import {PinchManager} from "../UserInput/PinchManager"; import {joystickBaseImg, joystickBaseKey, joystickThumbImg, joystickThumbKey} from "../Components/MobileJoystick"; @@ -353,31 +361,6 @@ export class GameScene extends ResizableScene implements CenterListener { } } - // helper for recursive group layer support - private createHelper(layers: ITiledMapLayer[], depth: integer, prefix: string): integer { - for(const layer of layers) { - if(layer.type === 'tilelayer') { - this.addLayer(this.Map.createStaticLayer(prefix + layer.name, this.Terrains, 0, 0).setDepth(depth)); - - const exitSceneUrl = this.getExitSceneUrl(layer); - if(exitSceneUrl !== undefined) { - this.loadNextGame(exitSceneUrl); - } - const exitUrl = this.getExitUrl(layer); - if(exitUrl !== undefined) { - this.loadNextGame(exitUrl); - } - } - if(layer.type === 'group') { - this.createHelper(layer.layers, depth, prefix + layer.name + '/'); - } - if(layer.type === 'objectgroup' && layer.name === 'floorLayer') { - depth = 10000; - } - } - return depth; - } - //hook create scene create(): void { gameManager.gameSceneIsCreated(this); @@ -411,9 +394,27 @@ export class GameScene extends ResizableScene implements CenterListener { //add layer on map this.Layers = new Array(); - - if (this.createHelper(this.mapFile.layers, -2, '') === -2) { - throw new Error('Your map MUST contain a layer of type "objectgroup" whose name is "floorLayer" that represents the layer characters are drawn at.'); + + let depth = -2; + for (const layer of this.gameMap.layersIterator) { + if (layer.type === 'tilelayer') { + this.addLayer(this.Map.createStaticLayer(layer.name, this.Terrains, 0, 0).setDepth(depth)); + + const exitSceneUrl = this.getExitSceneUrl(layer); + if (exitSceneUrl !== undefined) { + this.loadNextGame(exitSceneUrl); + } + const exitUrl = this.getExitUrl(layer); + if (exitUrl !== undefined) { + this.loadNextGame(exitUrl); + } + } + if (layer.type === 'objectgroup' && layer.name === 'floorLayer') { + depth = 10000; + } + } + if (depth === -2) { + throw new Error('Your map MUST contain a layer of type "objectgroup" whose name is "floorLayer" that represents the layer characters are drawn at. This layer cannot be contained in a group.'); } this.initStartXAndStartY(); @@ -963,20 +964,15 @@ ${escapedMessage} } } - private initPositionFromLayerNameHelper(layerName: string, layers : ITiledMapLayer[]) { - for (const layer of layers) { - if (layerName === layer.name && layer.type === 'tilelayer' && (layerName === defaultStartLayerName || this.isStartLayer(layer))) { + private initPositionFromLayerName(layerName: string) { + for (const layer of this.gameMap.layersIterator) { + if ((layerName === layer.name || layer.name.endsWith('/'+layerName)) && layer.type === 'tilelayer' && (layerName === defaultStartLayerName || this.isStartLayer(layer))) { const startPosition = this.startUser(layer); this.startX = startPosition.x + this.mapFile.tilewidth/2; this.startY = startPosition.y + this.mapFile.tileheight/2; - } else if (layer.type === 'group') { - this.initPositionFromLayerNameHelper(layerName, layer.layers); } } - } - private initPositionFromLayerName(layerName: string) { - this.initPositionFromLayerNameHelper(layerName, this.mapFile.layers); } private getExitUrl(layer: ITiledMapLayer): string|undefined { @@ -999,7 +995,7 @@ ${escapedMessage} } private getProperty(layer: ITiledMapLayer|ITiledMap, name: string): string|boolean|number|undefined { - const properties: ITiledMapLayerProperty[] = layer.properties; + const properties: ITiledMapLayerProperty[]|undefined = layer.properties; if (!properties) { return undefined; } @@ -1011,7 +1007,7 @@ ${escapedMessage} } private getProperties(layer: ITiledMapLayer|ITiledMap, name: string): (string|number|boolean|undefined)[] { - const properties: ITiledMapLayerProperty[] = layer.properties; + const properties: ITiledMapLayerProperty[]|undefined = layer.properties; if (!properties) { return []; } @@ -1025,7 +1021,7 @@ ${escapedMessage} await gameManager.loadMap(room, this.scene); } - private startUser(layer: ITiledMapLayer): PositionInterface { + private startUser(layer: ITiledMapTileLayer): PositionInterface { const tiles = layer.data; if (typeof(tiles) === 'string') { throw new Error('The content of a JSON map must be filled as a JSON array, not as a string'); diff --git a/front/src/Phaser/Map/ITiledMap.ts b/front/src/Phaser/Map/ITiledMap.ts index 6dfb4a2c..359b8e52 100644 --- a/front/src/Phaser/Map/ITiledMap.ts +++ b/front/src/Phaser/Map/ITiledMap.ts @@ -14,7 +14,7 @@ export interface ITiledMap { * Map orientation (orthogonal) */ orientation: string; - properties: ITiledMapLayerProperty[]; + properties?: ITiledMapLayerProperty[]; /** * Render order (right-down) @@ -24,6 +24,11 @@ export interface ITiledMap { tilewidth: number; tilesets: ITiledTileSet[]; version: number; + compressionlevel?: number; + infinite?: boolean; + nextlayerid?: number; + tiledversion?: string; + type?: string; } export interface ITiledMapLayerProperty { @@ -38,19 +43,35 @@ export interface ITiledMapLayerProperty { value: boolean }*/ -export interface ITiledMapLayer { +export type ITiledMapLayer = ITiledMapGroupLayer | ITiledMapObjectLayer | ITiledMapTileLayer; + +export interface ITiledMapGroupLayer { + id?: number, + name: string; + opacity: number; + properties?: ITiledMapLayerProperty[]; + + type: "group"; + visible: boolean; + x: number; + y: number; + /** + * Layers for group layer + */ + layers: ITiledMapLayer[]; +} + +export interface ITiledMapTileLayer { + id?: number, data: number[]|string; height: number; name: string; opacity: number; - properties: ITiledMapLayerProperty[]; - encoding: string; + properties?: ITiledMapLayerProperty[]; + encoding?: string; compression?: string; - /** - * Type of layer (tilelayer, objectgroup) - */ - type: string; + type: "tilelayer"; visible: boolean; width: number; x: number; @@ -59,13 +80,29 @@ export interface ITiledMapLayer { /** * Draw order (topdown (default), index) */ - draworder: string; - objects: ITiledMapObject[]; + draworder?: string; +} + +export interface ITiledMapObjectLayer { + id?: number, + height: number; + name: string; + opacity: number; + properties?: ITiledMapLayerProperty[]; + encoding?: string; + compression?: string; + + type: "objectgroup"; + visible: boolean; + width: number; + x: number; + y: number; /** - * Layers for group layer + * Draw order (topdown (default), index) */ - layers: this[]; + draworder?: string; + objects: ITiledMapObject[]; } export interface ITiledMapObject { diff --git a/front/src/Phaser/Map/LayersIterator.ts b/front/src/Phaser/Map/LayersIterator.ts new file mode 100644 index 00000000..501a5f7b --- /dev/null +++ b/front/src/Phaser/Map/LayersIterator.ts @@ -0,0 +1,44 @@ +import {ITiledMap, ITiledMapLayer} from "./ITiledMap"; + +/** + * Iterates over the layers of a map, flattening the grouped layers + */ +export class LayersIterator implements IterableIterator { + + private layers: ITiledMapLayer[] = []; + private pointer: number = 0; + + constructor(private map: ITiledMap) { + this.initLayersList(map.layers, ''); + } + + private initLayersList(layers : ITiledMapLayer[], prefix : string) { + for (const layer of layers) { + if (layer.type === 'group') { + this.initLayersList(layer.layers, prefix + layer.name + '/'); + } else { + const layerWithNewName = { ...layer }; + layerWithNewName.name = prefix+layerWithNewName.name; + this.layers.push(layerWithNewName); + } + } + } + + public next(): IteratorResult { + if (this.pointer < this.layers.length) { + return { + done: false, + value: this.layers[this.pointer++] + } + } else { + return { + done: true, + value: null + } + } + } + + [Symbol.iterator](): IterableIterator { + return new LayersIterator(this.map); + } +} diff --git a/front/tests/Phaser/Map/LayersIteratorTest.ts b/front/tests/Phaser/Map/LayersIteratorTest.ts new file mode 100644 index 00000000..3b9d0d9b --- /dev/null +++ b/front/tests/Phaser/Map/LayersIteratorTest.ts @@ -0,0 +1,147 @@ +import "jasmine"; +import {Room} from "../../../src/Connexion/Room"; +import {LayersIterator} from "../../../src/Phaser/Map/LayersIterator"; + +describe("Layers iterator", () => { + it("should iterate maps with no group", () => { + const layersIterator = new LayersIterator({ + "compressionlevel":-1, + "height":2, + "infinite":false, + "layers":[ + { + "data":[0, 0, 0, 0], + "height":2, + "id":1, + "name":"Tile Layer 1", + "opacity":1, + "type":"tilelayer", + "visible":true, + "width":2, + "x":0, + "y":0 + }, + { + "data":[0, 0, 0, 0], + "height":2, + "id":1, + "name":"Tile Layer 2", + "opacity":1, + "type":"tilelayer", + "visible":true, + "width":2, + "x":0, + "y":0 + }], + "nextlayerid":2, + "nextobjectid":1, + "orientation":"orthogonal", + "renderorder":"right-down", + "tiledversion":"2021.03.23", + "tileheight":32, + "tilesets":[], + "tilewidth":32, + "type":"map", + "version":1.5, + "width":2 + }) + + const layers = []; + for (const layer of layersIterator) { + layers.push(layer.name); + } + expect(layers).toEqual(['Tile Layer 1', 'Tile Layer 2']); + }); + + it("should iterate maps with recursive groups", () => { + const layersIterator = new LayersIterator({ + "compressionlevel":-1, + "height":2, + "infinite":false, + "layers":[ + { + "id":6, + "layers":[ + { + "id":5, + "layers":[ + { + "data":[0, 0, 0, 0], + "height":2, + "id":10, + "name":"Tile3", + "opacity":1, + "type":"tilelayer", + "visible":true, + "width":2, + "x":0, + "y":0 + }, + { + "data":[0, 0, 0, 0], + "height":2, + "id":9, + "name":"Tile2", + "opacity":1, + "type":"tilelayer", + "visible":true, + "width":2, + "x":0, + "y":0 + }], + "name":"Group 3", + "opacity":1, + "type":"group", + "visible":true, + "x":0, + "y":0 + }, + { + "id":7, + "layers":[ + { + "data":[0, 0, 0, 0], + "height":2, + "id":8, + "name":"Tile1", + "opacity":1, + "type":"tilelayer", + "visible":true, + "width":2, + "x":0, + "y":0 + }], + "name":"Group 2", + "opacity":1, + "type":"group", + "visible":true, + "x":0, + "y":0 + }], + "name":"Group 1", + "opacity":1, + "type":"group", + "visible":true, + "x":0, + "y":0 + }], + "nextlayerid":11, + "nextobjectid":1, + "orientation":"orthogonal", + "renderorder":"right-down", + "tiledversion":"2021.03.23", + "tileheight":32, + "tilesets":[], + "tilewidth":32, + "type":"map", + "version":1.5, + "width":2 + }) + + const layers = []; + for (const layer of layersIterator) { + layers.push(layer.name); + } + expect(layers).toEqual(['Group 1/Group 3/Tile3', 'Group 1/Group 3/Tile2', 'Group 1/Group 2/Tile1']); + }); +}); diff --git a/maps/tests/grouped_map.json b/maps/tests/grouped_map.json new file mode 100644 index 00000000..1e6c3e35 --- /dev/null +++ b/maps/tests/grouped_map.json @@ -0,0 +1,102 @@ +{ "compressionlevel":-1, + "height":10, + "infinite":false, + "layers":[ + { + "id":7, + "layers":[ + { + "data":[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], + "height":10, + "id":1, + "name":"floor", + "opacity":1, + "type":"tilelayer", + "visible":true, + "width":10, + "x":0, + "y":0 + }, + { + "data":[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + "height":10, + "id":2, + "name":"start", + "opacity":1, + "type":"tilelayer", + "visible":true, + "width":10, + "x":0, + "y":0 + }], + "name":"Group 2", + "opacity":1, + "type":"group", + "visible":true, + "x":0, + "y":0 + }, + { + "id":6, + "layers":[ + { + "data":[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 34, 34, 34, 34, 34, 0, 0, 0, 0, 0, 34, 34, 34, 34, 34, 0, 0, 0, 0, 0, 34, 34, 34, 34, 34, 0, 0, 0, 0, 0, 34, 34, 34, 34, 34, 0, 0, 0, 0, 0, 34, 34, 34, 34, 34, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + "height":10, + "id":5, + "name":"jitsiConf", + "opacity":1, + "properties":[ + { + "name":"jitsiRoom", + "type":"string", + "value":"myRoom" + }], + "type":"tilelayer", + "visible":true, + "width":10, + "x":0, + "y":0 + }], + "name":"Group 1", + "opacity":1, + "type":"group", + "visible":true, + "x":0, + "y":0 + }, + { + "draworder":"topdown", + "id":3, + "name":"floorLayer", + "objects":[], + "opacity":1, + "type":"objectgroup", + "visible":true, + "x":0, + "y":0 + }], + "nextlayerid":8, + "nextobjectid":1, + "orientation":"orthogonal", + "renderorder":"right-down", + "tiledversion":"2021.03.23", + "tileheight":32, + "tilesets":[ + { + "columns":11, + "firstgid":1, + "image":"tileset1.png", + "imageheight":352, + "imagewidth":352, + "margin":0, + "name":"tileset1", + "spacing":0, + "tilecount":121, + "tileheight":32, + "tilewidth":32 + }], + "tilewidth":32, + "type":"map", + "version":1.5, + "width":10 +} \ No newline at end of file From 6e5fa2c5149bd959b87dcd80019038b8b0a01978 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20N=C3=A9grier?= Date: Fri, 16 Apr 2021 16:41:40 +0200 Subject: [PATCH 5/5] Initiating CHANGELOG file --- CHANGELOG.md | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 CHANGELOG.md diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 00000000..93940b0c --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,10 @@ +## Version 1.3.0 - in dev + +### New Features + +* Maps can now contain "group" layers (layers that contain other layers) - #899 #779 (@Lurkars @moufmouf) + +### Updates + + +### Bug Fixes