// Texture Generator // Proceduralno generiranje tekstur in sprite-ov class TextureGenerator { // Generiraj player sprite (32x32px pixel art) static createPlayerSprite(scene, key = 'player') { if (scene.textures.exists(key)) return; const canvas = scene.textures.createCanvas(key, 32, 32); const ctx = canvas.getContext(); ctx.clearRect(0, 0, 32, 32); // Body ctx.fillStyle = '#A0522D'; // Sienna skin ctx.fillRect(10, 8, 12, 12); // Head ctx.fillStyle = '#2F4F4F'; // DarkSlateGray shirt ctx.fillRect(8, 20, 16, 12); // Eyes ctx.fillStyle = '#FFFFFF'; ctx.fillRect(12, 12, 2, 2); ctx.fillRect(18, 12, 2, 2); ctx.fillStyle = '#000000'; ctx.fillRect(13, 12, 1, 1); ctx.fillRect(19, 12, 1, 1); // Hair ctx.fillStyle = '#000000'; ctx.fillRect(10, 6, 12, 4); ctx.fillRect(8, 8, 2, 6); ctx.fillRect(22, 8, 2, 6); canvas.refresh(); } // Generiraj walking animacijo static createPlayerWalkSprite(scene, key = 'player_walk') { if (scene.textures.exists(key)) return; const canvas = scene.textures.createCanvas(key, 128, 32); const ctx = canvas.getContext(); // Simple placeholders for 4 frames for (let i = 0; i < 4; i++) { ctx.fillStyle = '#2F4F4F'; ctx.fillRect(i * 32 + 8, 6, 16, 26); } canvas.refresh(); } // Generiraj NPC sprite static createNPCSprite(scene, key = 'npc', type = 'zombie') { if (scene.textures.exists(key)) return; const canvas = scene.textures.createCanvas(key, 32, 32); const ctx = canvas.getContext(); ctx.clearRect(0, 0, 32, 32); ctx.fillStyle = (type === 'zombie') ? '#556B2F' : '#DEB887'; // OliveDrab or Burlywood ctx.fillRect(8, 6, 16, 26); // Body // Eyes (Red for zombie) ctx.fillStyle = (type === 'zombie') ? '#FF0000' : '#000000'; ctx.fillRect(10, 10, 4, 4); ctx.fillRect(20, 10, 4, 4); canvas.refresh(); } static createMerchantSprite(scene, key = 'merchant_texture') { if (scene.textures.exists(key)) return; console.log('🧙‍♂️ Creating Merchant Sprite Texture...'); try { const canvas = scene.textures.createCanvas(key, 32, 32); const ctx = canvas.getContext(); ctx.clearRect(0, 0, 32, 32); // Body (BRIGHT GOLD robe - zelo viden!) ctx.fillStyle = '#FFD700'; // Gold ctx.fillRect(8, 6, 16, 26); // Head ctx.fillStyle = '#FFE4C4'; // Bisque skin ctx.fillRect(10, 4, 12, 12); // Hat (Red Merchants Hat) ctx.fillStyle = '#8B0000'; // DarkRed ctx.fillRect(8, 2, 16, 4); ctx.fillRect(10, 0, 12, 2); // Hat Top // Backpack (Brown - visible on sides) ctx.fillStyle = '#8B4513'; ctx.fillRect(4, 10, 4, 14); // Left side pack ctx.fillRect(24, 10, 4, 14); // Right side pack // Straps ctx.fillStyle = '#A0522D'; ctx.fillRect(8, 10, 16, 2); // Eyes ctx.fillStyle = '#000000'; ctx.fillRect(13, 8, 2, 2); ctx.fillRect(17, 8, 2, 2); // Beard (White) ctx.fillStyle = '#F5F5F5'; ctx.fillRect(10, 12, 12, 4); ctx.fillRect(12, 16, 8, 2); canvas.refresh(); console.log('✅ Merchant Sprite Created!'); } catch (error) { console.error('❌ ERROR creating merchant sprite:', error); } } static createCloudSprite(scene, key = 'cloud') { if (scene.textures.exists(key)) return; const canvas = scene.textures.createCanvas(key, 64, 32); const ctx = canvas.getContext(); ctx.clearRect(0, 0, 64, 32); ctx.fillStyle = 'rgba(255,255,255,0.6)'; ctx.beginPath(); ctx.arc(20, 20, 15, 0, Math.PI * 2); ctx.fill(); ctx.beginPath(); ctx.arc(35, 15, 18, 0, Math.PI * 2); ctx.fill(); ctx.beginPath(); ctx.arc(50, 20, 12, 0, Math.PI * 2); ctx.fill(); canvas.refresh(); } static createCropSprite(scene, key, stage = 4) { if (scene.textures.exists(key)) return; const canvas = scene.textures.createCanvas(key, 32, 32); const ctx = canvas.getContext(); ctx.clearRect(0, 0, 32, 32); ctx.fillStyle = '#228B22'; // Stem const h = stage * 5; ctx.fillRect(14, 32 - h, 4, h); if (stage >= 3) { ctx.fillStyle = '#FFD700'; // Wheat head ctx.beginPath(); ctx.arc(16, 32 - h, 6, 0, Math.PI * 2); ctx.fill(); } if (stage === 5) { // Withered ctx.fillStyle = '#8B4513'; ctx.fillRect(14, 20, 4, 12); } canvas.refresh(); } static createStructureSprite(scene, key, type) { if (scene.textures.exists(key)) return; const width = (type === 'house' || type === 'ruin') ? 64 : 32; const height = (type === 'house' || type === 'ruin') ? 64 : 32; const canvas = scene.textures.createCanvas(key, width, height); const ctx = canvas.getContext(); ctx.clearRect(0, 0, width, height); if (type === 'ruin') { // Isometric Ruin / Rocks for user ctx.fillStyle = '#696969'; // DimGray // Big Rock 1 ctx.beginPath(); ctx.arc(20, 50, 14, 0, Math.PI * 2); ctx.fill(); // Big Rock 2 ctx.beginPath(); ctx.arc(45, 55, 12, 0, Math.PI * 2); ctx.fill(); // Details ctx.fillStyle = '#555555'; ctx.beginPath(); ctx.arc(25, 45, 6, 0, Math.PI * 2); ctx.fill(); } else { // Generic box for others ctx.fillStyle = '#8B4513'; ctx.fillRect(0, 0, width, height); } canvas.refresh(); } // ========== 3D VOLUMETRIC GENERATORS (RESTORED) ========== // Generiraj 3D volumetric tree (Minecraft-style) static createTreeSprite(scene, key = 'tree') { if (scene.textures.exists(key)) return; const size = 64; const height = 96; // Taller for 3D effect const canvas = scene.textures.createCanvas(key, size, height); const ctx = canvas.getContext(); ctx.clearRect(0, 0, size, height); // Helper to draw isometric-ish cube face const drawCube = (x, y, w, h, d, colorTop, colorSide, colorFront) => { // Front face ctx.fillStyle = colorFront; ctx.fillRect(x, y + d, w, h); // Top face (fake perspective) ctx.fillStyle = colorTop; ctx.beginPath(); ctx.moveTo(x, y + d); ctx.lineTo(x + d, y); ctx.lineTo(x + w + d, y); ctx.lineTo(x + w, y + d); ctx.closePath(); ctx.fill(); // Side face ctx.fillStyle = colorSide; ctx.beginPath(); ctx.moveTo(x + w, y + d); ctx.lineTo(x + w + d, y); ctx.lineTo(x + w + d, y + h); ctx.lineTo(x + w, y + h + d); ctx.closePath(); ctx.fill(); }; // Trunk const trunkColor = '#8B4513'; const trunkTop = '#A0522D'; const trunkDark = '#663300'; drawCube(24, 60, 16, 24, 8, trunkTop, trunkDark, trunkColor); // Leaves chunks (Minecraft style) const leafColor = '#228B22'; // ForestGreen const leafTop = '#32CD32'; // LimeGreen const leafDark = '#006400'; // DarkGreen // Bottom layer drawCube(12, 30, 40, 20, 10, leafTop, leafDark, leafColor); // Top layer drawCube(20, 10, 24, 20, 8, leafTop, leafDark, leafColor); canvas.refresh(); } // Generiraj 3D volumetric Rock (Gray Cubes) static createRockSprite(scene, key = 'rock') { if (scene.textures.exists(key)) return; const size = 48; const canvas = scene.textures.createCanvas(key, size, size); const ctx = canvas.getContext(); ctx.clearRect(0, 0, size, size); // Simple Voxel Draw const drawVoxel = (x, y, c) => { ctx.fillStyle = c; ctx.fillRect(x, y, 10, 10); ctx.fillStyle = '#444444'; // Side ctx.fillRect(x + 10, y, 4, 10); ctx.fillStyle = '#333333'; // Bottom ctx.fillRect(x, y + 10, 10, 4); }; const gray = '#808080'; drawVoxel(10, 25, gray); drawVoxel(20, 20, gray); drawVoxel(15, 15, gray); canvas.refresh(); } // Generiraj 3D flower (simple volumetric) static createFlowerSprite(scene, key = 'flower') { if (scene.textures.exists(key)) return; const size = 32; const canvas = scene.textures.createCanvas(key, size, size); const ctx = canvas.getContext(); ctx.clearRect(0, 0, size, size); ctx.fillStyle = '#228B22'; // Stem ctx.fillRect(15, 10, 2, 10); ctx.fillStyle = '#FF69B4'; // Flower ctx.fillRect(12, 8, 8, 8); canvas.refresh(); } static createBushSprite(scene, key = 'bush') { if (scene.textures.exists(key)) return; const size = 32; const canvas = scene.textures.createCanvas(key, size, size); const ctx = canvas.getContext(); ctx.clearRect(0, 0, size, size); ctx.fillStyle = '#228B22'; ctx.beginPath(); ctx.arc(16, 16, 12, 0, Math.PI * 2); ctx.fill(); ctx.fillStyle = 'red'; // Berries ctx.beginPath(); ctx.arc(12, 12, 2, 0, Math.PI * 2); ctx.fill(); ctx.beginPath(); ctx.arc(20, 18, 2, 0, Math.PI * 2); ctx.fill(); canvas.refresh(); } static createGravestoneSprite(scene, key = 'gravestone') { if (scene.textures.exists(key)) return; const canvas = scene.textures.createCanvas(key, 32, 32); const ctx = canvas.getContext(); ctx.clearRect(0, 0, 32, 32); ctx.fillStyle = '#808080'; ctx.fillRect(8, 8, 16, 24); ctx.beginPath(); ctx.arc(16, 8, 8, Math.PI, 0); ctx.fill(); canvas.refresh(); } static createToolSprites(scene) { // Placeholder tool generation if (!scene.textures.exists('item_axe')) { const c = scene.textures.createCanvas('item_axe', 32, 32); const x = c.getContext(); x.fillStyle = 'brown'; x.fillRect(14, 10, 4, 18); x.fillStyle = 'gray'; x.fillRect(12, 10, 8, 6); c.refresh(); } if (!scene.textures.exists('item_pickaxe')) { const c = scene.textures.createCanvas('item_pickaxe', 32, 32); const x = c.getContext(); x.fillStyle = 'brown'; x.fillRect(14, 10, 4, 18); x.fillStyle = 'gray'; x.fillRect(8, 12, 16, 4); c.refresh(); } if (!scene.textures.exists('item_hoe')) { const c = scene.textures.createCanvas('item_hoe', 32, 32); const x = c.getContext(); x.fillStyle = 'brown'; x.fillRect(14, 10, 4, 18); // Ročaj x.fillStyle = 'gray'; x.fillRect(10, 8, 12, 4); // Rezilo motike c.refresh(); } if (!scene.textures.exists('item_sword')) { const c = scene.textures.createCanvas('item_sword', 32, 32); const x = c.getContext(); x.fillStyle = 'brown'; x.fillRect(14, 10, 4, 14); // Ročaj x.fillStyle = 'gray'; x.fillRect(12, 8, 8, 12); // Rezilo meča x.fillStyle = 'gold'; x.fillRect(14, 21, 4, 2); // Guard c.refresh(); } } static createItemSprites(scene) { // Placeholder item generation const items = [ { name: 'wood', color: '#8B4513' }, // Rjava { name: 'stone', color: '#808080' }, // Siva { name: 'seeds', color: '#90EE90' }, // Svetlo zelena { name: 'wheat', color: '#FFD700' }, // Zlata { name: 'item_bone', color: '#F5F5DC' } // Beige ]; items.forEach(item => { const it = typeof item === 'string' ? item : item.name; const color = typeof item === 'string' ? 'gold' : item.color; const k = (it.startsWith('item_')) ? it : 'item_' + it; if (!scene.textures.exists(k)) { const c = scene.textures.createCanvas(k, 32, 32); const x = c.getContext(); x.clearRect(0, 0, 32, 32); x.fillStyle = color; x.beginPath(); x.arc(16, 16, 10, 0, Math.PI * 2); x.fill(); c.refresh(); } }); } static createSaplingSprite(scene, key = 'tree_sapling') { if (scene.textures.exists(key)) return; const size = 32; const canvas = scene.textures.createCanvas(key, size, size); const ctx = canvas.getContext(); ctx.clearRect(0, 0, size, size); // Majhno steblo ctx.fillStyle = '#8B4513'; ctx.fillRect(14, 20, 4, 12); // Parnosti listov ctx.fillStyle = '#32CD32'; ctx.beginPath(); ctx.arc(12, 18, 4, 0, Math.PI * 2); ctx.fill(); ctx.beginPath(); ctx.arc(20, 18, 4, 0, Math.PI * 2); ctx.fill(); ctx.beginPath(); ctx.arc(16, 12, 5, 0, Math.PI * 2); ctx.fill(); canvas.refresh(); } // Helper to generate ALL textures at once generateAll() { TextureGenerator.createPlayerSprite(this.scene); TextureGenerator.createPlayerWalkSprite(this.scene); TextureGenerator.createNPCSprite(this.scene, 'npc', 'zombie'); TextureGenerator.createMerchantSprite(this.scene, 'merchant_texture'); TextureGenerator.createFlowerSprite(this.scene); TextureGenerator.createBushSprite(this.scene); TextureGenerator.createSaplingSprite(this.scene, 'tree_sapling'); // Dodano TextureGenerator.createTreeSprite(this.scene); // Volumetric TextureGenerator.createRockSprite(this.scene); // Volumetric TextureGenerator.createCloudSprite(this.scene); TextureGenerator.createCropSprite(this.scene, 'crop_stage_1', 1); TextureGenerator.createCropSprite(this.scene, 'crop_stage_2', 2); TextureGenerator.createCropSprite(this.scene, 'crop_stage_3', 3); TextureGenerator.createCropSprite(this.scene, 'crop_stage_4', 4); TextureGenerator.createCropSprite(this.scene, 'crop_stage_5', 5); TextureGenerator.createGravestoneSprite(this.scene); TextureGenerator.createToolSprites(this.scene); TextureGenerator.createItemSprites(this.scene); } constructor(scene) { this.scene = scene; } }