// Weather Enhancements - Wind, transitions, tree sway class WeatherEnhancementsSystem { constructor(scene) { this.scene = scene; // Wind system this.windStrength = 0.5; // 0-1 scale this.windDirection = 0; // angle in radians this.windChangeTimer = 0; this.windChangeDuration = 3000; // Change wind every 3 seconds // Tree sway animations this.swayingTrees = new Map(); // tree → tween // Weather transition this.transitionDuration = 2000; // 2 seconds smooth transition this.isTransitioning = false; console.log('🌬️ WeatherEnhancementsSystem initialized'); } // Update wind parameters update(delta) { this.updateWind(delta); this.updateTreeSway(delta); } // Gradually change wind over time updateWind(delta) { this.windChangeTimer += delta; if (this.windChangeTimer > this.windChangeDuration) { this.windChangeTimer = 0; // Smoothly change wind const targetStrength = Math.random(); // 0-1 const targetDirection = Math.random() * Math.PI * 2; // 0-360° // Tween wind strength this.scene.tweens.add({ targets: this, windStrength: targetStrength, windDirection: targetDirection, duration: 2000, ease: 'Sine.easeInOut' }); } } // Apply wind effect to rain particles applyWindToRain(rainEmitter) { if (!rainEmitter) return; // Calculate wind offset for rain angle const baseAngle = 270; // Straight down const windAngle = this.windStrength * 30; // Max 30° deviation const windDirectionDegrees = Phaser.Math.RadToDeg(this.windDirection); // Apply horizontal wind speed const windSpeedX = Math.cos(this.windDirection) * this.windStrength * 100; // Update rain emitter config (if using Phaser 3.60+ particles) try { rainEmitter.setConfig({ speedX: { min: windSpeedX - 20, max: windSpeedX + 20 } }); } catch (e) { // Fallback for older Phaser versions console.warn('Wind effect requires Phaser 3.60+'); } } // Make a tree sway in the wind addSwayingTree(tree, treeSprite) { if (!treeSprite || this.swayingTrees.has(tree)) return; // Calculate sway amount based on wind const maxSwayAngle = 2 + (this.windStrength * 3); // 2-5 degrees const swaySpeed = 1500 - (this.windStrength * 500); // 1000-1500ms // Create sway tween const tween = this.scene.tweens.add({ targets: treeSprite, angle: { from: -maxSwayAngle, to: maxSwayAngle }, duration: swaySpeed, yoyo: true, repeat: -1, ease: 'Sine.easeInOut' }); this.swayingTrees.set(tree, tween); } // Update tree sway based on current wind updateTreeSway(delta) { for (const [tree, tween] of this.swayingTrees) { // Adjust tween speed based on wind strength if (tween && tween.isPlaying()) { // Dynamic sway intensity const maxSwayAngle = 2 + (this.windStrength * 3); // Update would require recreating tween // For now, trees sway at initial speed } } } // Stop tree sway removeSwayingTree(tree) { const tween = this.swayingTrees.get(tree); if (tween) { tween.stop(); this.swayingTrees.delete(tree); } } // Smooth weather transition transitionWeather(fromWeather, toWeather, onComplete) { if (this.isTransitioning) return; this.isTransitioning = true; console.log(`🌤️ Weather transitioning: ${fromWeather} → ${toWeather}`); // Get weather system const weatherSystem = this.scene.weatherSystem; if (!weatherSystem) { this.isTransitioning = false; if (onComplete) onComplete(); return; } // Fade out old weather if (weatherSystem.rainEmitter) { this.scene.tweens.add({ targets: weatherSystem.rainEmitter, alpha: { from: 1, to: 0 }, duration: this.transitionDuration / 2, onComplete: () => { // Clear old weather weatherSystem.clearWeather(); // Start new weather if (toWeather === 'rain') { weatherSystem.startRain(false); } else if (toWeather === 'storm') { weatherSystem.startRain(true); } // Fade in new weather if (weatherSystem.rainEmitter) { weatherSystem.rainEmitter.setAlpha(0); this.scene.tweens.add({ targets: weatherSystem.rainEmitter, alpha: { from: 0, to: 1 }, duration: this.transitionDuration / 2, onComplete: () => { this.isTransitioning = false; if (onComplete) onComplete(); } }); } else { this.isTransitioning = false; if (onComplete) onComplete(); } } }); } else { // No old weather to fade out, just start new if (toWeather === 'rain') { weatherSystem.startRain(false); } else if (toWeather === 'storm') { weatherSystem.startRain(true); } this.isTransitioning = false; if (onComplete) onComplete(); } } // Get current wind info (for UI or other systems) getWindInfo() { return { strength: this.windStrength, direction: this.windDirection, speedKmh: Math.round(this.windStrength * 50), // 0-50 km/h directionName: this.getWindDirectionName(this.windDirection) }; } // Convert wind direction to compass name getWindDirectionName(radians) { const degrees = Phaser.Math.RadToDeg(radians); const normalized = ((degrees % 360) + 360) % 360; if (normalized < 22.5 || normalized >= 337.5) return 'N'; if (normalized < 67.5) return 'NE'; if (normalized < 112.5) return 'E'; if (normalized < 157.5) return 'SE'; if (normalized < 202.5) return 'S'; if (normalized < 247.5) return 'SW'; if (normalized < 292.5) return 'W'; return 'NW'; } // Clean up destroy() { // Stop all tree sway tweens for (const [tree, tween] of this.swayingTrees) { if (tween) tween.stop(); } this.swayingTrees.clear(); console.log('🌬️ WeatherEnhancementsSystem destroyed'); } }