From 74919b5a0b583a4ddec41ee5cf0bc533a81591c3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20N=C3=A9grier?= Date: Wed, 19 Jun 2024 16:55:51 +0200 Subject: [PATCH] fix: Fixing animation optimization issue When a tile was used several times in the same animation, it would be improperly renumbered if the tile was already optimized before. This prevented animations going back and forth to work correctly. --- src/Optimizer.ts | 26 ++++++++++++++++++++------ 1 file changed, 20 insertions(+), 6 deletions(-) diff --git a/src/Optimizer.ts b/src/Optimizer.ts index bbeeeb7..2b10fac 100644 --- a/src/Optimizer.ts +++ b/src/Optimizer.ts @@ -12,7 +12,11 @@ sharp.cache(false); export class Optimizer { private optimizedMap: ITiledMap; - private optimizedTiles: Map; + /** + * A map mapping the old tile id to the new tile id (global) and to the new tile id in the current tileset + * @private + */ + private optimizedTiles: Map; private optimizedTilesets: ITiledMapEmbeddedTileset[]; private currentTilesetOptimization: ITiledMapEmbeddedTileset; private currentExtractedTiles: Promise[]; @@ -30,7 +34,7 @@ export class Optimizer { private readonly outputPath: string ) { this.optimizedMap = map; - this.optimizedTiles = new Map(); + this.optimizedTiles = new Map(); this.optimizedTilesets = []; this.tileSize = options?.tile?.size ?? 32; this.outputSize = options?.output?.tileset?.size ? options?.output?.tileset?.size : 512; @@ -219,7 +223,7 @@ export class Optimizer { const unflippedTileId = tileId - minBitId; - const existantNewTileId = this.optimizedTiles.get(unflippedTileId); + const existantNewTileId = this.optimizedTiles.get(unflippedTileId)?.global; if (existantNewTileId) { return existantNewTileId + minBitId; @@ -265,7 +269,10 @@ export class Optimizer { if (tileData && tileData.animation) { if (tileData.animation.length + this.currentExtractedTiles.length > this.tilesetMaxTileCount) { for (let i = 1; i < this.tilesetMaxTileCount - this.currentExtractedTiles.length; i++) { - this.optimizedTiles.set(-1, this.optimizedTiles.size + i); + this.optimizedTiles.set(-1, { + global: this.optimizedTiles.size + i, + local: 0, + }); } await this.currentTilesetRendering(); @@ -275,7 +282,10 @@ export class Optimizer { const newTileId = this.optimizedTiles.size + 1; - this.optimizedTiles.set(unflippedTileId, newTileId); + this.optimizedTiles.set(unflippedTileId, { + global: newTileId, + local: this.currentExtractedTiles.length, + }); let newTileData: ITiledMapTile | undefined = undefined; @@ -322,10 +332,14 @@ export class Optimizer { newTileData.animation = []; for (const frame of tileData.animation) { await this.optimizeNewTile(oldFirstgid + frame.tileid); + const newTile = this.optimizedTiles.get(oldFirstgid + frame.tileid)?.local; + if (newTile === undefined) { + throw new Error(`Undefined tile in animation for ${oldFirstgid + frame.tileid}`); + } newTileData.animation.push({ duration: frame.duration, - tileid: this.currentExtractedTiles.length - 1, + tileid: newTile, }); } }