-
Notifications
You must be signed in to change notification settings - Fork 1
/
TILEDGraphics.ts
89 lines (75 loc) · 2.76 KB
/
TILEDGraphics.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
import * as PIXI from 'pixi.js';
window['PIXI'] = PIXI;
global['PIXI'] = PIXI;
import 'pixi-tilemap';
export default class TILEDGraphics extends PIXI.Container {
private readonly textureCache = [];
constructor(tilemap, path) {
super();
fetch(this.getTilesetPath(path, tilemap.tilesets[0])).then(res => res.json()).then(tileset => {
PIXI.Loader.shared.add('tileset', this.getTilesetImagePath(path, tileset));
PIXI.Loader.shared.load((loader, resources) => {
const baseTexture = resources.tileset.texture.baseTexture;
tilemap.layers.forEach(layer => {
if (!layer.visible || layer.type != "tilelayer")
return;
const container = this.addChild(new PIXI.Container()) as PIXI.Container;
container.alpha = layer.opacity;
let tileNum = 0;
let currTileLayer;
const processLayerData = (layerData) => {
layerData.data.forEach((id, index) => {
const i = index % layerData.width + layerData.x;
const j = Math.floor(index / layerData.width) + layerData.y;
if (tileNum++ % 16384 == 0) {
currTileLayer = container.addChild(new PIXI.tilemap.CompositeRectTileLayer());
}
const x = i * tileset.tilewidth + (layerData.offsetx || 0);
const y = j * tileset.tileheight + (layerData.offsety || 0);
this.createTile(baseTexture, tileset, currTileLayer, id, x, y);
});
}
if (layer.data) {
processLayerData(layer);
} else if (layer.chunks) {
layer.chunks.forEach(processLayerData);
}
});
});
});
}
private createTile(baseTexture, tileset, container, id: number, x, y) {
if (id == 0)
return;
const tilesetId = this.clearFlags(id) - 1;
if (!this.textureCache[tilesetId]) {
this.createTexture(baseTexture, tileset, tilesetId);
}
const texture = this.textureCache[tilesetId];
container.addFrame(texture, x, y, id);
}
private createTexture(baseTexture, tileset, tilesetId: number) {
let x = tileset.tilewidth * (tilesetId % tileset.columns);
let y = tileset.tileheight * Math.floor(tilesetId / tileset.columns);
let width = tileset.tilewidth;
let height = tileset.tileheight;
this.textureCache[tilesetId] = new PIXI.Texture(baseTexture, new PIXI.Rectangle(x, y, width, height));
}
private clearFlags(tile: number) {
tile &= ~(0x20000000 | 0x40000000 | 0x80000000);
return tile;
}
private getTilesetPath(path, tileset) {
const splitPath = path.split('/');
const split = tileset.source.split('.');
split[split.length - 1] = 'json';
const filename = split.join('.');
splitPath[splitPath.length - 1] = filename;
return splitPath.join('/');
}
private getTilesetImagePath(path, tileset) {
const splitPath = path.split('/');
splitPath[splitPath.length - 1] = tileset.image;
return splitPath.join('/');
}
}