///
namespace gdjs {
export interface RuntimeScene {
tileMapCollisionMaskManager: gdjs.TileMap.TileMapRuntimeManager;
}
export namespace TileMap {
import PIXI = GlobalPIXIModule.PIXI;
const logger = new gdjs.Logger('Tilemap object');
/**
* A holder to share tile maps across the 2 extension objects.
*
* Every instance with the same files path in properties will
* share the same {@link EditableTileMap} and {@link TileTextureCache}.
*
* To use a tile map with collisions, a user can create 4 objects:
* - one for the the rendering
* - one for the solid platforms
* - one for the jumpthrus
* - one for the ladders
*
* To avoid to have 4 copies of the same tile map in memory, this manager
* puts the tile map in cache and avoid unnecessary parsing.
*
* @see {@link TileMapManager}
*/
export class TileMapRuntimeManager {
private _runtimeScene: gdjs.RuntimeScene;
/**
* Delegate that actually manage the caches without anything specific to
* GDJS.
* It allows to factorize code with the IDE.
*/
private _manager: TileMapHelper.TileMapManager;
/**
* @param runtimeScene The scene.
*/
private constructor(runtimeScene: gdjs.RuntimeScene) {
this._runtimeScene = runtimeScene;
this._manager = new TileMapHelper.TileMapManager();
}
/**
* @param runtimeScene Where to set the manager instance.
* @returns The shared manager.
*/
static getManager(
runtimeScene: gdjs.RuntimeScene
): TileMapRuntimeManager {
if (!runtimeScene.tileMapCollisionMaskManager) {
// Create the shared manager if necessary.
runtimeScene.tileMapCollisionMaskManager = new TileMapRuntimeManager(
runtimeScene
);
}
return runtimeScene.tileMapCollisionMaskManager;
}
/**
* @param tileMapJsonResourceName The resource name of the tile map.
* @param tileSetJsonResourceName The resource name of the tile set.
* @param callback A function called when the tile map is parsed.
*/
getOrLoadTileMap(
tileMapJsonResourceName: string,
tileSetJsonResourceName: string,
callback: (tileMap: TileMapHelper.EditableTileMap | null) => void
): void {
this._manager.getOrLoadTileMap(
this._loadTiledMap.bind(this),
tileMapJsonResourceName,
tileSetJsonResourceName,
pako,
callback
);
}
/**
* @param getTexture The method that loads the atlas image file in memory.
* @param atlasImageResourceName The resource name of the atlas image.
* @param tileMapJsonResourceName The resource name of the tile map.
* @param tileSetJsonResourceName The resource name of the tile set.
* @param callback A function called when the tiles textures are split.
*/
getOrLoadTextureCache(
getTexture: (textureName: string) => PIXI.BaseTexture,
atlasImageResourceName: string,
tileMapJsonResourceName: string,
tileSetJsonResourceName: string,
callback: (textureCache: TileMapHelper.TileTextureCache | null) => void
): void {
this._manager.getOrLoadTextureCache(
this._loadTiledMap.bind(this),
getTexture,
atlasImageResourceName,
tileMapJsonResourceName,
tileSetJsonResourceName,
callback
);
}
/**
* Parse both JSON and set the content of the tile set in the right
* attribute in the tile map to merge both parsed data.
*/
private _loadTiledMap(
tileMapJsonResourceName: string,
tileSetJsonResourceName: string,
callback: (tiledMap: TileMapHelper.TiledMap | null) => void
): void {
this._runtimeScene
.getGame()
.getJsonManager()
.loadJson(tileMapJsonResourceName, (error, tileMapJsonData) => {
if (error) {
logger.error(
'An error happened while loading a Tilemap JSON data:',
error
);
callback(null);
return;
}
const tiledMap = tileMapJsonData as TileMapHelper.TiledMap;
if (tileSetJsonResourceName) {
this._runtimeScene
.getGame()
.getJsonManager()
.loadJson(tileSetJsonResourceName, (error, tileSetJsonData) => {
if (error) {
logger.error(
'An error happened while loading Tileset JSON data:',
error
);
callback(null);
return;
}
const tileSet = tileSetJsonData as TileMapHelper.TiledTileset;
tileSet.firstgid = tiledMap.tilesets[0].firstgid;
tiledMap.tilesets = [tileSet];
callback(tiledMap);
});
} else {
callback(tiledMap);
}
});
}
}
}
}