Avtomatska obdelava tileset slik - 3877 ločenih objektov in TSX datotek

- Ustvarjen skript za ločevanje objektov iz tileset slik (obdelaj_tilesete.py)
- Odstranjevanje zelenega ozadja (#00FF00) iz vseh slik
- Ločevanje posameznih objektov iz multi-object slik
- Pomanjševanje na 50% originalne velikosti
- Obdelanih 234 slik  3877 ločenih objektov

- Ustvarjen skript za generiranje TSX datotek (generiraj_tsx_datoteke.py)
- Avtomatsko generiranje 3877 TSX datotek za Tiled Map Editor
- Pravilna XML struktura za vsak tileset
- Avtomatska detekcija velikosti objektov
- Relativne poti do slik

Rezultati:
- assets/narezano_loceno/ - 3877 ločenih PNG objektov
- assets/tilesets_auto/ - 3877 TSX datotek za Tiled
- Dokumentacija in navodila za uporabo

Vse pripravljeno za uporabo v Tiled Map Editor!
This commit is contained in:
2025-12-21 15:36:42 +01:00
parent bc58894dd9
commit 7eb1a5874a
7225 changed files with 13919 additions and 57 deletions

View File

@@ -68,7 +68,7 @@ const config = {
debug: false
}
},
scene: [BootScene, PreloadScene, StoryScene, GameScene, UIScene],
scene: [BootScene, PreloadScene, TiledTestScene, StoryScene, GameScene, UIScene],
scale: {
mode: Phaser.Scale.FIT,
autoCenter: Phaser.Scale.CENTER_BOTH

View File

@@ -33,6 +33,7 @@ class PreloadScene extends Phaser.Scene {
// 🗺️ TILED MAP (JSON export from Tiled Editor)
this.load.tilemapTiledJSON('farm_map', 'assets/maps/farm_map.json');
this.load.tilemapTiledJSON('micro_farm_128x128', 'assets/maps/micro_farm_128x128.json'); // 🌾 Testna farma
this.load.image('grass_tileset_img', 'assets/tilesets/grass.png');
this.load.image('water_tileset_img', 'assets/tilesets/water.png');
this.load.image('decorations_tileset_img', 'assets/tilesets/decorations.png');
@@ -762,10 +763,12 @@ class PreloadScene extends Phaser.Scene {
console.log('✅ PreloadScene: Assets loaded!');
window.gameState.currentScene = 'PreloadScene';
// Go directly to main menu (StoryScene)
// 🗺️ ZAČASNO: Gre naravnost v TiledTestScene za testiranje
// Ko končaš testiranje, spremeni nazaj v 'StoryScene'
this.time.delayedCall(500, () => {
console.log('🎮 Starting StoryScene...');
this.scene.start('StoryScene');
console.log('🗺️ Starting TiledTestScene (TESTING MODE)...');
this.scene.start('TiledTestScene'); // ← ZAČASNO ZA TEST
// this.scene.start('StoryScene'); // ← NORMALNO
});
}

View File

@@ -0,0 +1,225 @@
// 🗺️ Tiled Test Scene - Za testiranje Tiled map v igri
class TiledTestScene extends Phaser.Scene {
constructor() {
super({ key: 'TiledTestScene' });
this.map = null;
this.layers = [];
}
create() {
console.log('🗺️ Tiled Test Scene: Initializing...');
// Set light blue sky background
this.cameras.main.setBackgroundColor('#87CEEB');
// Try to load the tilemap
try {
// Load the micro farm tilemap
this.map = this.make.tilemap({ key: 'micro_farm_128x128' });
console.log(`📐 Map size: ${this.map.width}x${this.map.height} tiles`);
console.log(`📐 Tile size: ${this.map.tileWidth}x${this.map.tileHeight}px`);
console.log(`📐 Map dimensions: ${this.map.widthInPixels}x${this.map.heightInPixels}px`);
// List all tilesets in the map
console.log('📦 Tilesets in map:');
this.map.tilesets.forEach((tileset, i) => {
console.log(` ${i + 1}. ${tileset.name} (${tileset.total} tiles)`);
});
// List all layers in the map
console.log('📚 Layers in map:');
this.map.layers.forEach((layer, i) => {
console.log(` ${i + 1}. ${layer.name} (${layer.width}x${layer.height})`);
});
// Add tilesets - mora biti enako kot v .tmx!
// BELEŽKA: Ta imena morajo biti enaka kot v micro_farm_128x128.tmx
const tilesets = {};
// Poskusi dodati tilesets
this.map.tilesets.forEach(tilesetData => {
console.log(`🔧 Adding tileset: ${tilesetData.name}`);
// Map tileset names to Phaser texture keys
const textureKey = this.getTilesetTextureKey(tilesetData.name);
if (this.textures.exists(textureKey)) {
try {
tilesets[tilesetData.name] = this.map.addTilesetImage(tilesetData.name, textureKey);
console.log(` ✅ Tileset "${tilesetData.name}" added (using texture: ${textureKey})`);
} catch (e) {
console.error(` ❌ Failed to add tileset "${tilesetData.name}":`, e.message);
}
} else {
console.warn(` ⚠️ Texture "${textureKey}" not found for tileset "${tilesetData.name}"`);
}
});
// Create layers
console.log('🎨 Creating layers...');
this.map.layers.forEach(layerData => {
try {
// Get tilesets for this layer
const layerTilesets = Object.values(tilesets);
const layer = this.map.createLayer(layerData.name, layerTilesets, 0, 0);
if (layer) {
this.layers.push(layer);
console.log(` ✅ Layer "${layerData.name}" created`);
} else {
console.warn(` ⚠️ Failed to create layer "${layerData.name}"`);
}
} catch (e) {
console.error(` ❌ Error creating layer "${layerData.name}":`, e.message);
}
});
// Set camera bounds
const mapWidth = this.map.widthInPixels;
const mapHeight = this.map.heightInPixels;
this.cameras.main.setBounds(0, 0, mapWidth, mapHeight);
// Zoom out to see the whole 128x128 map
// 128 tiles * 48px = 6144px
// Typical screen is ~1920x1080
// Zoom = 1920 / 6144 ≈ 0.3 (adjust for comfort)
const zoomLevel = 0.4;
this.cameras.main.setZoom(zoomLevel);
console.log(`📷 Camera zoom set to ${zoomLevel}`);
// Center camera on middle of map
this.cameras.main.centerOn(mapWidth / 2, mapHeight / 2);
// Enable camera controls
this.setupControls();
console.log('✅ Tiled Test Scene: Map loaded successfully!');
console.log('🎮 Controls:');
console.log(' Arrow Keys: Move camera');
console.log(' Q/E: Zoom in/out');
console.log(' R: Reset camera');
console.log(' ESC: Return to main game');
// Add UI text
this.addInfoText();
} catch (e) {
console.error('❌ Failed to load tilemap:', e);
// Show error message
this.add.text(100, 100, 'ERROR: Failed to load micro farm map!\nCheck console for details.', {
fontSize: '32px',
fill: '#ff0000',
backgroundColor: '#ffffff',
padding: { x: 20, y: 20 }
});
}
}
/**
* Map Tiled tileset names to Phaser texture keys
*/
getTilesetTextureKey(tilesetName) {
// Map tileset names to loaded texture keys in PreloadScene
const mapping = {
'grass': 'tileset_grass',
'dirt': 'tileset_dirt',
'water': 'tileset_water',
'decorations': 'tileset_decorations',
// Add more mappings as needed
};
return mapping[tilesetName] || `tileset_${tilesetName}`;
}
setupControls() {
// Cursor keys for camera movement
this.cursors = this.input.keyboard.createCursorKeys();
// Zoom controls
this.input.keyboard.on('keydown-Q', () => {
const newZoom = this.cameras.main.zoom + 0.1;
this.cameras.main.setZoom(Math.min(newZoom, 2.0));
this.updateInfoText();
});
this.input.keyboard.on('keydown-E', () => {
const newZoom = this.cameras.main.zoom - 0.1;
this.cameras.main.setZoom(Math.max(newZoom, 0.1));
this.updateInfoText();
});
// Reset camera
this.input.keyboard.on('keydown-R', () => {
if (this.map) {
this.cameras.main.setZoom(0.4);
this.cameras.main.centerOn(this.map.widthInPixels / 2, this.map.heightInPixels / 2);
this.updateInfoText();
}
});
// Return to main menu
this.input.keyboard.on('keydown-ESC', () => {
console.log('🔙 Returning to StoryScene...');
this.scene.start('StoryScene');
});
}
addInfoText() {
const style = {
fontSize: '16px',
fill: '#ffffff',
backgroundColor: '#000000',
padding: { x: 10, y: 10 }
};
this.infoText = this.add.text(10, 10, '', style).setScrollFactor(0).setDepth(1000);
this.updateInfoText();
}
updateInfoText() {
if (!this.infoText || !this.map) return;
const zoom = this.cameras.main.zoom.toFixed(2);
const camX = Math.round(this.cameras.main.scrollX);
const camY = Math.round(this.cameras.main.scrollY);
this.infoText.setText([
'🗺️ TILED TEST MODE',
`Map: ${this.map.width}x${this.map.height} tiles`,
`Zoom: ${zoom}x (Q/E to adjust)`,
`Camera: (${camX}, ${camY})`,
`Layers: ${this.layers.length}`,
'',
'Controls:',
' Arrow Keys - Move',
' Q/E - Zoom',
' R - Reset',
' ESC - Exit'
]);
}
update(time, delta) {
// Camera movement with arrow keys
const speed = 10 / this.cameras.main.zoom; // Adjust speed based on zoom
if (this.cursors.left.isDown) {
this.cameras.main.scrollX -= speed;
} else if (this.cursors.right.isDown) {
this.cameras.main.scrollX += speed;
}
if (this.cursors.up.isDown) {
this.cameras.main.scrollY -= speed;
} else if (this.cursors.down.isDown) {
this.cameras.main.scrollY += speed;
}
// Update info text periodically
if (time % 500 < delta) {
this.updateInfoText();
}
}
}