// tiledLoader.js : charge une map Tiled (.tmj + .tsx) et la dessine en iso import { Sprite, Assets } from 'pixi.js'; import { iso, getTw, getTh } from './renderer.js'; export async function loadTiledMap(mapPath) { // baseUrl = dossier du .tmj (les .tsx sont a cote) const baseUrl = mapPath.substring(0, mapPath.lastIndexOf('/') + 1); const map = await fetch(mapPath).then(r => r.json()); // parse les .tsx (XML) referencements (firstgid + chemin image par tile id) const tilesets = []; for (const ts of map.tilesets) { const tsxText = await fetch(baseUrl + ts.source).then(r => r.text()); const xml = new DOMParser().parseFromString(tsxText, 'text/xml'); const tiles = {}; for (const tile of xml.querySelectorAll('tile')) { const id = parseInt(tile.getAttribute('id')); const img = tile.querySelector('image'); if (img) { tiles[id] = { src: baseUrl + img.getAttribute('source'), w: parseInt(img.getAttribute('width')), h: parseInt(img.getAttribute('height')), }; } } tilesets.push({ firstgid: ts.firstgid, tiles }); } // precharger toutes les textures const urls = []; for (const ts of tilesets) { for (const id in ts.tiles) urls.push(ts.tiles[id].src); } await Assets.load(urls); return { map, tilesets }; } function _gidToTile(gid, tilesets) { // chercher dans le bon tileset (firstgid descendant) for (let i = tilesets.length - 1; i >= 0; i--) { if (gid >= tilesets[i].firstgid) { return tilesets[i].tiles[gid - tilesets[i].firstgid] || null; } } return null; } export function drawTiledMap(layer, data) { const { map, tilesets } = data; const W = map.width; const H = map.height; const tw = getTw(); const th = getTh(); // reference : la base (footprint iso) d'un sprite Kenney fait 256x128 px // au tw courant, on veut que cette base remplisse 1 unite monde (tw x th px) const REF_TILE_W = 256; const scale = tw / REF_TILE_W; for (const tlayer of map.layers) { if (tlayer.type !== 'tilelayer') continue; if (tlayer.visible === false) continue; for (let i = 0; i < tlayer.data.length; i++) { const gid = tlayer.data[i]; if (gid === 0) continue; // 0 = case vide const tile = _gidToTile(gid, tilesets); if (!tile) continue; const col = i % W; const row = Math.floor(i / W); // centrer la map sur (0, 0) const wx = col - (W - 1) / 2; const wy = row - (H - 1) / 2; const tex = Assets.get(tile.src); if (!tex) continue; const sprite = new Sprite(tex); sprite.anchor.set(0.5, 1.0); // base centree sur la tile, le sprite "monte" const p = iso(wx, wy); sprite.x = p.x; sprite.y = p.y + th / 2; // decalage half pour que la pointe basse de la diamond touche la base sprite.scale.set(scale); layer.addChild(sprite); } } }