// Particle Enhancements System - Advanced particle effects for gameplay class ParticleEnhancementsSystem { constructor(scene) { this.scene = scene; // Particle pools for efficiency this.sparklePool = []; this.dustPool = []; this.particleTextures = new Set(); // Create particle textures this.createParticleTextures(); console.log('✨ ParticleEnhancementsSystem initialized'); } // Create procedural particle textures createParticleTextures() { // Sparkle particle (star-shaped) if (!this.scene.textures.exists('sparkle')) { const graphics = this.scene.make.graphics({ x: 0, y: 0, add: false }); graphics.fillStyle(0xffffff, 1); graphics.fillCircle(4, 4, 4); graphics.generateTexture('sparkle', 8, 8); graphics.destroy(); this.particleTextures.add('sparkle'); } // Dust particle (cloud-shaped) if (!this.scene.textures.exists('dust')) { const graphics = this.scene.make.graphics({ x: 0, y: 0, add: false }); graphics.fillStyle(0xdddddd, 0.6); graphics.fillCircle(3, 3, 3); graphics.generateTexture('dust', 6, 6); graphics.destroy(); this.particleTextures.add('dust'); } // Leaf particle (for harvest) if (!this.scene.textures.exists('leaf')) { const graphics = this.scene.make.graphics({ x: 0, y: 0, add: false }); graphics.fillStyle(0x4a9d5f, 1); graphics.fillRect(0, 0, 4, 6); graphics.generateTexture('leaf', 4, 6); graphics.destroy(); this.particleTextures.add('leaf'); } // Star particle (for special effects) if (!this.scene.textures.exists('star')) { const graphics = this.scene.make.graphics({ x: 0, y: 0, add: false }); graphics.fillStyle(0xffee88, 1); // 5-pointed star const cx = 5, cy = 5, spikes = 5, outerRadius = 5, innerRadius = 2; let rot = Math.PI / 2 * 3; let x = cx; let y = cy; const step = Math.PI / spikes; graphics.beginPath(); graphics.moveTo(cx, cy - outerRadius); for (let i = 0; i < spikes; i++) { x = cx + Math.cos(rot) * outerRadius; y = cy + Math.sin(rot) * outerRadius; graphics.lineTo(x, y); rot += step; x = cx + Math.cos(rot) * innerRadius; y = cy + Math.sin(rot) * innerRadius; graphics.lineTo(x, y); rot += step; } graphics.lineTo(cx, cy - outerRadius); graphics.closePath(); graphics.fillPath(); graphics.generateTexture('star', 10, 10); graphics.destroy(); this.particleTextures.add('star'); } } // Enhanced craft sparkles (when crafting completes) craftSparkles(x, y, color = [0xffffff, 0xffee88, 0xffaa00]) { const emitter = this.scene.add.particles(x, y, 'sparkle', { speed: { min: 50, max: 150 }, angle: { min: 0, max: 360 }, scale: { start: 1, end: 0 }, tint: color, alpha: { start: 1, end: 0 }, lifespan: 1000, quantity: 20, blendMode: 'ADD', emitting: false }); emitter.setDepth(999999); emitter.explode(20); // Burst of 20 particles // Auto-destroy after particles fade this.scene.time.delayedCall(1200, () => { emitter.destroy(); }); return emitter; } // Walk dust clouds (when player walks) walkDust(x, y, direction = 'down') { // Only spawn on grass/dirt tiles const tileSize = 48; const tileX = Math.floor(x / tileSize); const tileY = Math.floor(y / tileSize); if (this.scene.terrainSystem) { const tile = this.scene.terrainSystem.getTile(tileX, tileY); if (!tile || (tile.type !== 'grass' && tile.type !== 'dirt')) { return null; // No dust on water/pavement } } const emitter = this.scene.add.particles(x, y + 10, 'dust', { speed: { min: 10, max: 30 }, angle: { min: 0, max: 360 }, scale: { start: 0.5, end: 1.5 }, alpha: { start: 0.4, end: 0 }, lifespan: 500, quantity: 2, frequency: 100, blendMode: 'NORMAL', tint: 0xccaa88, // Dusty brown emitting: false }); emitter.setDepth(this.scene.player ? this.scene.player.sprite.depth - 1 : 100); emitter.explode(2); // Small puff // Auto-destroy this.scene.time.delayedCall(600, () => { emitter.destroy(); }); return emitter; } // Harvest particle burst (when harvesting crops) harvestBurst(x, y, cropType = 'generic') { // Determine particle color based on crop let particleColors = [0x4a9d5f, 0x90EE90]; // Default green let particleTexture = 'leaf'; if (cropType === 'wheat' || cropType === 'grain') { particleColors = [0xFFD700, 0xFFA500]; // Golden particleTexture = 'sparkle'; } else if (cropType === 'carrot' || cropType === 'root') { particleColors = [0xFF6B35, 0xFFA500]; // Orange particleTexture = 'leaf'; } else if (cropType === 'berry' || cropType === 'fruit') { particleColors = [0xFF1744, 0xFF6B9D]; // Red/Pink particleTexture = 'sparkle'; } const emitter = this.scene.add.particles(x, y, particleTexture, { speed: { min: 80, max: 150 }, angle: { min: -120, max: -60 }, // Upward spray scale: { start: 1, end: 0.3 }, tint: particleColors, alpha: { start: 1, end: 0 }, lifespan: 800, quantity: 15, gravityY: 200, // Gravity pull blendMode: 'NORMAL', emitting: false }); emitter.setDepth(200000); emitter.explode(15); // Auto-destroy this.scene.time.delayedCall(1000, () => { emitter.destroy(); }); // Play success sound if (this.scene.soundManager && this.scene.soundManager.beepPickup) { this.scene.soundManager.beepPickup(); } return emitter; } // Dig/Till soil particles (when using hoe) digParticles(x, y) { const emitter = this.scene.add.particles(x, y, 'dust', { speed: { min: 40, max: 80 }, angle: { min: -140, max: -40 }, // Upward scale: { start: 0.8, end: 0.2 }, alpha: { start: 0.6, end: 0 }, tint: [0x8b6f47, 0x6b4423], // Brown soil lifespan: 600, quantity: 10, gravityY: 150, blendMode: 'NORMAL', emitting: false }); emitter.setDepth(200000); emitter.explode(10); this.scene.time.delayedCall(800, () => { emitter.destroy(); }); return emitter; } // Plant seed sparkle (when planting) plantSparkle(x, y) { const emitter = this.scene.add.particles(x, y, 'sparkle', { speed: { min: 20, max: 50 }, angle: { min: 0, max: 360 }, scale: { start: 0.6, end: 0 }, tint: 0x90EE90, // Light green alpha: { start: 0.8, end: 0 }, lifespan: 500, quantity: 8, blendMode: 'ADD', emitting: false }); emitter.setDepth(200000); emitter.explode(8); this.scene.time.delayedCall(600, () => { emitter.destroy(); }); return emitter; } // Build completion effect (when placing building) buildComplete(x, y, width = 48, height = 48) { // Create corner sparkles const corners = [ { x: x - width / 2, y: y - height / 2 }, // Top-left { x: x + width / 2, y: y - height / 2 }, // Top-right { x: x - width / 2, y: y + height / 2 }, // Bottom-left { x: x + width / 2, y: y + height / 2 } // Bottom-right ]; corners.forEach((corner, index) => { this.scene.time.delayedCall(index * 100, () => { this.craftSparkles(corner.x, corner.y, [0xFFD700, 0xFFA500]); }); }); // Center burst this.scene.time.delayedCall(400, () => { this.craftSparkles(x, y, [0xffffff, 0xFFD700]); }); } // Level up / achievement effect levelUpEffect(x, y) { // Ring explosion const emitter = this.scene.add.particles(x, y, 'star', { speed: { min: 100, max: 200 }, angle: { min: 0, max: 360 }, scale: { start: 1.5, end: 0 }, tint: [0xFFD700, 0xFFEE88, 0xFFFFFF], alpha: { start: 1, end: 0 }, lifespan: 1500, quantity: 30, blendMode: 'ADD', emitting: false }); emitter.setDepth(999999); emitter.explode(30); // Upward rising stars const rising = this.scene.add.particles(x, y, 'star', { speedY: { min: -100, max: -50 }, speedX: { min: -20, max: 20 }, scale: { start: 0.8, end: 0 }, tint: 0xFFD700, alpha: { start: 1, end: 0 }, lifespan: 2000, quantity: 1, frequency: 100, blendMode: 'ADD' }); rising.setDepth(999999); // Stop after 2 seconds this.scene.time.delayedCall(2000, () => { rising.stop(); }); // Cleanup this.scene.time.delayedCall(3500, () => { emitter.destroy(); rising.destroy(); }); return { burst: emitter, rising }; } // Damage impact effect (when hit) damageImpact(x, y, color = 0xFF0000) { const emitter = this.scene.add.particles(x, y, 'sparkle', { speed: { min: 50, max: 100 }, angle: { min: 0, max: 360 }, scale: { start: 0.8, end: 0 }, tint: color, alpha: { start: 1, end: 0 }, lifespan: 400, quantity: 12, blendMode: 'ADD', emitting: false }); emitter.setDepth(999999); emitter.explode(12); this.scene.time.delayedCall(500, () => { emitter.destroy(); }); return emitter; } // Heal/Restore effect healEffect(x, y) { const emitter = this.scene.add.particles(x, y, 'sparkle', { speedY: { min: -80, max: -40 }, speedX: { min: -20, max: 20 }, scale: { start: 0.6, end: 0 }, tint: [0x00FF00, 0x90EE90, 0xFFFFFF], alpha: { start: 1, end: 0 }, lifespan: 1000, quantity: 1, frequency: 80, blendMode: 'ADD' }); emitter.setDepth(999999); this.scene.time.delayedCall(1000, () => { emitter.stop(); }); this.scene.time.delayedCall(2000, () => { emitter.destroy(); }); return emitter; } // Clean up all particles destroy() { // Destroy created textures for (const textureName of this.particleTextures) { if (this.scene.textures.exists(textureName)) { this.scene.textures.remove(textureName); } } this.particleTextures.clear(); console.log('✨ ParticleEnhancementsSystem destroyed'); } }