Files
novafarma/tools/setup_tiled.js
David Kotnik 7264ec6fc0 feat: complete Style 32 overhaul & Tiled integration fix
- Enforced 'Style 32 - Dark Chibi Vector' for all ground assets.
- Fixed critical Prologue-to-Game crash (function renaming).
- Implemented Tiled JSON/TMX auto-conversion.
- Updated Asset Manager to visualize 1800+ assets.
- Cleaned up project structure (new assets/grounds folder).
- Auto-Ground logic added to GameScene.js.
2026-01-11 20:08:56 +01:00

119 lines
4.0 KiB
JavaScript

const fs = require('fs');
const path = require('path');
const TILED_DIR = 'assets/tiled';
const TARGET_MAPS = ['faza1_kmetija.json', 'demo_test.json'];
const ASSET_DIRS = ['../buildings', '../terrain', '../props']; // Relative to TILED_DIR
// 1. Gather Images
const tiles = []; // ARRAY for Tiled JSON compatibility
let nextId = 0; // Start ID at 0
let grassId = null;
ASSET_DIRS.forEach(dir => {
const fullDir = path.join(__dirname, '..', 'assets', dir.replace('../', ''));
if (fs.existsSync(fullDir)) {
const files = fs.readdirSync(fullDir);
files.forEach(file => {
if (file.endsWith('.png')) {
const relPath = path.join(dir, file);
// Add to array
tiles.push({
id: nextId,
image: relPath,
imageheight: 64, // Placeholder, Tiled will try to read actual
imagewidth: 64
});
// Identify Grass
if (file.includes('grass') || file.includes('resource_pile_food')) { // Fallback
if (grassId === null) grassId = nextId;
}
nextId++;
}
});
}
});
console.log(`🔍 Found ${tiles.length} assets.`);
console.log(`🌿 Grass ID: ${grassId}`);
// 2. Setup Tileset Object
const autoTileset = {
"columns": 0,
"grid": { "height": 1, "orientation": "orthogonal", "width": 1 },
"margin": 0,
"name": "Auto_Assets",
"spacing": 0,
"tilecount": tiles.length,
"tileheight": 256,
"tiles": tiles, // Array!
"tilewidth": 256,
"type": "tileset_image_collection"
};
// 3. Process Maps
TARGET_MAPS.forEach(mapFile => {
const mapPath = path.join(TILED_DIR, mapFile);
if (!fs.existsSync(mapPath)) {
console.warn(`⚠️ Map not found: ${mapPath}`);
return;
}
try {
const mapData = JSON.parse(fs.readFileSync(mapPath, 'utf8'));
// A. Inject Tileset
mapData.tilesets = [autoTileset];
// B. Auto-Ground (Fill Layer 1 with Grass)
const mapWidth = 100;
const mapHeight = 100;
mapData.width = mapWidth;
mapData.height = mapHeight;
// Find Ground Layer
const groundLayer = mapData.layers.find(l => l.name === 'Ground');
if (groundLayer && grassId !== null) {
groundLayer.width = mapWidth;
groundLayer.height = mapHeight;
groundLayer.data = new Array(mapWidth * mapHeight).fill(grassId + 1); // +1 because GID is local ID + firstgid (1)
// Wait, for image collections, keys match the ID.
// But map data uses GID (Global Tile ID).
// If firstgid is 1 (default for first tileset), then tile with ID 0 is GID 1.
// So tile with ID X is GID X + 1.
console.log(`✅ Filled Ground in ${mapFile} with GID ${grassId + 1}`);
}
// C. Demo Setup (Landmarks)
if (mapFile === 'demo_test.json') {
const objectLayer = mapData.layers.find(l => l.name === 'Objects');
if (objectLayer) {
objectLayer.width = mapWidth;
objectLayer.height = mapHeight;
// Add 5 random buildings
const randomIds = tiles.slice(0, 5).map(t => t.id);
const objData = new Array(mapWidth * mapHeight).fill(0);
randomIds.forEach((tileId, index) => {
const x = 10 + (index * 10);
const y = 15;
const idx = y * mapWidth + x;
if (idx < objData.length) objData[idx] = tileId + 1; // +1 GID
});
objectLayer.data = objData;
console.log(`✅ Placed 5 landmarks in ${mapFile}`);
}
}
// Save
fs.writeFileSync(mapPath, JSON.stringify(mapData, null, 4));
console.log(`💾 Saved updated ${mapFile}`);
} catch (e) {
console.error(`❌ Error processing ${mapFile}:`, e);
}
});