| Server IP : 167.235.67.158 / Your IP : 216.73.216.95 Web Server : Apache System : Linux ubuntu-8gb-nbg1-1 6.8.0-111-generic #111-Ubuntu SMP PREEMPT_DYNAMIC Sat Apr 11 23:16:02 UTC 2026 x86_64 User : root ( 0) PHP Version : 8.3.6 Disable Function : NONE MySQL : OFF | cURL : ON | WGET : ON | Perl : ON | Python : OFF | Sudo : ON | Pkexec : OFF Directory : /var/www/bc.the-word.com/game-template/new/ |
Upload File : |
const fs = require('fs');
const path = require('path');
const { DOMParser } = require('@xmldom/xmldom');
const xpath = require('xpath');
// === CONFIG ===
const inputSVG = path.join(__dirname, 'level_editor.svg');
const outputJSON = path.join(__dirname, 'level.json');
const ignoredGroups = ['AllObjects', 'Background'];
// === LOAD SVG ===
const svgContent = fs.readFileSync(inputSVG, 'utf8');
const doc = new DOMParser().parseFromString(svgContent, 'image/svg+xml');
// === XPATH HELPERS ===
const select = xpath.useNamespaces({
svg: 'http://www.w3.org/2000/svg',
xlink: 'http://www.w3.org/1999/xlink',
});
// === PARSE GROUPS ===
const groups = select('//svg:g', doc);
const levelData = {};
for (const group of groups) {
const groupId = group.getAttribute('id');
if (!groupId || ignoredGroups.includes(groupId)) continue;
if (!levelData[groupId]) levelData[groupId] = [];
const uses = select('.//svg:use', group);
for (const use of uses) {
const href = use.getAttributeNS('http://www.w3.org/1999/xlink', 'href') || '';
const type = href.replace(/^#/, '') || 'Unknown';
const transform = use.getAttribute('transform') || '';
let x = 0, y = 0;
let flipX = false;
let rotation = 0;
// Check for translate coordinates (handle numbers like .5, -1.23, 100, etc.)
const translateMatch = transform.match(/translate\((-?\d*\.?\d+)[ ,](-?\d*\.?\d+)\)/);
if (translateMatch) {
x = parseFloat(translateMatch[1]);
y = parseFloat(translateMatch[2]);
}
// Check for rotation (handle rotate(angle) or rotate(angle x y))
const rotateMatch = transform.match(/rotate\((-?\d*\.?\d+)(?:[ ,](-?\d*\.?\d+)[ ,](-?\d*\.?\d+))?\)/);
if (rotateMatch) {
rotation = parseFloat(rotateMatch[1]);
// Normalize rotation to 0, 90, 180, 270
rotation = Math.round(rotation / 90) * 90;
rotation = ((rotation % 360) + 360) % 360; // Ensure positive 0-359 range
}
// Get sprite dimensions from the use element
const width = parseFloat(use.getAttribute('width') || 0);
const height = parseFloat(use.getAttribute('height') || 0);
// Check for scale(1 -1) which indicates horizontal flip
if (transform.includes('scale(1 -1)') || transform.includes('scale(1,-1)')) {
flipX = true;
}
// Convert from SVG top-left positioning to Phaser center positioning
if (flipX) {
// For flipped items, the x coordinate in SVG represents the right edge
// after the flip transform, so we need to subtract half width instead
x -= width / 2;
} else {
// For normal items, add half width to get center
x += width / 2;
}
// Y positioning is the same for both flipped and normal items
y += height / 2;
// Global offset - shift everything left by 10 pixels
x -= 5;
const objectData = { type, x, y };
if (flipX) {
objectData.flipX = true;
}
if (rotation !== 0) {
objectData.rotation = rotation;
}
// Debug logging for spawn points and spikeys
if (type === 'Spawn') {
console.log(`Translate match: ${translateMatch}`);
console.log(`X: ${x}, Y: ${y}`);
console.log(`Width: ${width}, Height: ${height}`);
console.log(`Transform: ${transform}`);
console.log(`FlipX: ${flipX}`);
}
// Debug logging for spikeys to verify rotation parsing
if (type === 'Spikey') {
console.log(`Spikey found:`);
console.log(` Transform: ${transform}`);
console.log(` Rotation: ${rotation}°`);
console.log(` Position: (${x}, ${y})`);
}
levelData[groupId].push(objectData);
}
}
// === OUTPUT JSON ===
fs.writeFileSync(outputJSON, JSON.stringify(levelData, null, 2));
console.log(`✅ Level data written to: ${outputJSON}`);