/
TileMapRuntimeManager.ts
163 lines (157 loc) · 5.68 KB
/
TileMapRuntimeManager.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
/// <reference path="helper/TileMapHelper.d.ts" />
namespace gdjs {
export interface RuntimeInstanceContainer {
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 _instanceContainer: gdjs.RuntimeInstanceContainer;
/**
* Delegate that actually manage the caches without anything specific to
* GDJS.
* It allows to factorize code with the IDE.
*/
private _manager: TileMapHelper.TileMapManager;
/**
* @param instanceContainer The instance container.
*/
private constructor(instanceContainer: gdjs.RuntimeInstanceContainer) {
this._instanceContainer = instanceContainer;
this._manager = new TileMapHelper.TileMapManager();
}
/**
* @param instanceContainer Where to set the manager instance.
* @returns The shared manager.
*/
static getManager(
instanceContainer: gdjs.RuntimeInstanceContainer
): TileMapRuntimeManager {
if (!instanceContainer.tileMapCollisionMaskManager) {
// Create the shared manager if necessary.
instanceContainer.tileMapCollisionMaskManager = new TileMapRuntimeManager(
instanceContainer
);
}
return instanceContainer.tileMapCollisionMaskManager;
}
/**
* @param tileMapJsonResourceName The resource name of the tile map.
* @param tileSetJsonResourceName The resource name of the tile set.
* @param levelIndex The level of the tile map.
* @param callback A function called when the tile map is parsed.
*/
getOrLoadTileMap(
tileMapJsonResourceName: string,
tileSetJsonResourceName: string,
levelIndex: number,
callback: (tileMap: TileMapHelper.EditableTileMap | null) => void
): void {
this._manager.getOrLoadTileMap(
this._loadTileMap.bind(this),
tileMapJsonResourceName,
tileSetJsonResourceName,
levelIndex,
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 levelIndex The level of the tile map.
* @param callback A function called when the tiles textures are split.
*/
getOrLoadTextureCache(
getTexture: (textureName: string) => PIXI.BaseTexture<PIXI.Resource>,
atlasImageResourceName: string,
tileMapJsonResourceName: string,
tileSetJsonResourceName: string,
levelIndex: number,
callback: (textureCache: TileMapHelper.TileTextureCache | null) => void
): void {
this._manager.getOrLoadTextureCache(
this._loadTileMap.bind(this),
getTexture,
atlasImageResourceName,
tileMapJsonResourceName,
tileSetJsonResourceName,
levelIndex,
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 _loadTileMap(
tileMapJsonResourceName: string,
tileSetJsonResourceName: string,
callback: (tileMap: TileMapHelper.TileMap | null) => void
): void {
this._instanceContainer
.getGame()
.getJsonManager()
.loadJson(tileMapJsonResourceName, (error, tileMapJsonData) => {
if (error) {
logger.error(
'An error happened while loading a Tilemap JSON data:',
error
);
callback(null);
return;
}
const tileMap = TileMapHelper.TileMapManager.identify(
tileMapJsonData
);
if (!tileMap) {
callback(null);
return;
}
if (tileMap.kind === 'tiled' && tileSetJsonResourceName) {
this._instanceContainer
.getGame()
.getJsonManager()
.loadJson(tileSetJsonResourceName, (error, tileSetJsonData) => {
if (error) {
logger.error(
'An error happened while loading Tileset JSON data:',
error
);
callback(null);
return;
}
const tiledMap = tileMap.data;
const tileSet = tileSetJsonData as TileMapHelper.TiledTileset;
tileSet.firstgid = tiledMap.tilesets[0].firstgid;
tiledMap.tilesets = [tileSet];
callback(tileMap);
});
} else {
callback(tileMap);
}
});
}
}
}
}