združen time in weather

This commit is contained in:
2025-12-07 04:39:45 +01:00
parent 03a9cd46a2
commit 9c01c44ebe
5 changed files with 199 additions and 322 deletions

View File

@@ -1,138 +1,170 @@
class WeatherSystem {
constructor(scene) {
this.scene = scene;
this.currentWeather = 'clear'; // clear, rain, storm, fog
this.weatherDuration = 0;
this.maxWeatherDuration = 30000; // 30s per weather cycle
// Weather effects containers
this.rainParticles = [];
this.overlay = null;
// --- Time Configuration ---
this.fullDaySeconds = 300; // 5 minutes = 24 game hours
this.gameTime = 8; // Start at 8:00
this.dayCount = 1;
// --- Weather Configuration ---
this.currentWeather = 'clear';
this.weatherDuration = 0;
this.maxWeatherDuration = 10000; // Random duration logic handles this
this.rainParticles = []; // {x, y, speed, length}
// --- State ---
this.currentPhase = 'day';
this.init();
}
init() {
// No local overlay - we use UI Scene
// Start weather cycle
this.changeWeather();
}
getOverlay() {
const uiScene = this.scene.scene.get('UIScene');
if (uiScene && uiScene.weatherGraphics) {
return uiScene.weatherGraphics;
if (uiScene && uiScene.overlayGraphics) {
return uiScene.overlayGraphics;
}
return null;
}
changeWeather() {
// Clean up old weather
this.clearWeather();
// Random new weather
const weathers = ['clear', 'clear', 'rain', 'fog']; // Clear more common
this.currentWeather = weathers[Math.floor(Math.random() * weathers.length)];
this.weatherDuration = 0;
console.log(`🌦️ Weather changed to: ${this.currentWeather}`);
// Apply new weather effects
this.applyWeather();
}
applyWeather() {
if (this.currentWeather === 'rain') {
this.startRain();
// Play rain sound
if (this.scene.soundManager) {
this.scene.soundManager.playRainSound();
}
} else if (this.currentWeather === 'fog') {
this.applyFog();
} else if (this.currentWeather === 'storm') {
this.startRain(true);
// Play rain sound (louder?)
if (this.scene.soundManager) {
this.scene.soundManager.playRainSound();
}
} else {
// Clear weather - stop ambient sounds
if (this.scene.soundManager) {
this.scene.soundManager.stopRainSound();
}
}
}
startRain(heavy = false) {
const width = this.scene.scale.width;
const height = this.scene.scale.height;
// Create rain drops (keep logic for drops)
const dropCount = heavy ? 150 : 100;
for (let i = 0; i < dropCount; i++) {
const drop = {
x: Math.random() * width,
y: Math.random() * height,
speed: heavy ? Phaser.Math.Between(400, 600) : Phaser.Math.Between(200, 400),
length: heavy ? Phaser.Math.Between(10, 15) : Phaser.Math.Between(5, 10)
};
this.rainParticles.push(drop);
}
// No drawing here - handled in renderWeather
}
applyFog() {
// No drawing here - handled in renderWeather
}
clearWeather() {
this.rainParticles = [];
// No clearing here - handled by DayNightSystem clearing the frame
}
update(delta) {
this.weatherDuration += delta;
// 1. Update Time
this.updateTime(delta);
// Change weather periodically
// 2. Update Weather Logic (Durations, Changes)
this.updateWeatherLogic(delta);
// 3. Update Physics (Rain drops)
this.updateWeatherPhysics(delta);
// 4. Render Atmosphere (Time + Weather)
this.render();
}
updateTime(delta) {
const seconds = delta / 1000;
const gameHoursPerRealSecond = 24 / this.fullDaySeconds;
this.gameTime += seconds * gameHoursPerRealSecond;
if (this.gameTime >= 24) {
this.gameTime -= 24;
this.dayCount++;
console.log(`🌞 Day ${this.dayCount} started!`);
}
// Update Phase
const phase = this.getPhase(this.gameTime);
if (phase !== this.currentPhase) {
this.currentPhase = phase;
console.log(`🌅 Time of Day: ${phase} (${Math.floor(this.gameTime)}:00)`);
}
// Update UI Clock
const uiScene = this.scene.scene.get('UIScene');
if (uiScene && uiScene.clockText) {
const hours = Math.floor(this.gameTime);
const minutes = Math.floor((this.gameTime - hours) * 60);
const timeString = `${hours.toString().padStart(2, '0')}:${minutes.toString().padStart(2, '0')}`;
uiScene.clockText.setText(`Day ${this.dayCount} - ${timeString}`);
}
}
getPhase(hour) {
if (hour >= 5 && hour < 7) return 'dawn';
if (hour >= 7 && hour < 18) return 'day';
if (hour >= 18 && hour < 20) return 'dusk';
return 'night';
}
updateWeatherLogic(delta) {
this.weatherDuration += delta;
if (this.weatherDuration > this.maxWeatherDuration) {
this.changeWeather();
}
// Always render active weather
if (this.currentWeather !== 'clear') {
this.renderWeather(delta);
}
}
renderWeather(delta) {
const overlay = this.getOverlay();
if (!overlay) return;
const height = this.scene.scale.height;
const width = this.scene.scale.width;
// FOG
if (this.currentWeather === 'fog') {
overlay.fillStyle(0xcccccc, 0.4);
overlay.fillRect(0, 0, width, height);
return;
}
// RAIN / STORM
updateWeatherPhysics(delta) {
if (this.currentWeather === 'rain' || this.currentWeather === 'storm') {
// Update physics
const width = this.scene.scale.width;
const height = this.scene.scale.height;
for (const drop of this.rainParticles) {
drop.y += (drop.speed * delta) / 1000;
// Wrap around
if (drop.y > height) {
drop.y = -10;
drop.x = Math.random() * width;
}
}
}
}
// Darken background for storm/rain (additive to DayNight)
render() {
const overlay = this.getOverlay();
if (!overlay) return;
// IMPORTANT: Clear previous frame to avoid buildup
overlay.clear();
const width = this.scene.scale.width;
const height = this.scene.scale.height;
// --- LAYER 1: Day/Night Cycle ---
this.renderDayNight(overlay, width, height);
// --- LAYER 2: Weather Effects (Fog, Rain darkness) ---
this.renderWeatherEffects(overlay, width, height);
}
renderDayNight(overlay, width, height) {
const hour = this.gameTime;
let color = 0x000033; // Default night
let alpha = 0;
if (hour >= 0 && hour < 5) { // Deep Night
color = 0x000033; alpha = 0.6;
} else if (hour >= 5 && hour < 7) { // Dawn
color = 0xFF6B35;
const progress = (hour - 5) / 2;
alpha = 0.6 - (progress * 0.6);
} else if (hour >= 7 && hour < 18) { // Day
alpha = 0;
} else if (hour >= 18 && hour < 20) { // Dusk
color = 0x8B4789;
const progress = (hour - 18) / 2;
alpha = progress * 0.5;
} else if (hour >= 20 && hour < 24) { // Night
color = 0x000033;
const progress = (hour - 20) / 4;
alpha = 0.5 + (progress * 0.1);
}
if (alpha > 0) {
overlay.fillStyle(color, alpha);
overlay.fillRect(0, 0, width, height);
}
}
renderWeatherEffects(overlay, width, height) {
// Fog
if (this.currentWeather === 'fog') {
overlay.fillStyle(0xcccccc, 0.4);
overlay.fillRect(0, 0, width, height);
}
// Rain / Storm
if (this.currentWeather === 'rain' || this.currentWeather === 'storm') {
const isDark = this.currentWeather === 'storm' ? 0.3 : 0.2;
// Additive darkness for storm
overlay.fillStyle(0x000033, isDark);
overlay.fillRect(0, 0, width, height);
@@ -147,13 +179,65 @@ class WeatherSystem {
}
}
getCurrentWeather() {
return this.currentWeather;
changeWeather() {
this.clearWeather();
const rand = Math.random();
if (rand < 0.6) {
this.currentWeather = 'clear';
this.maxWeatherDuration = Phaser.Math.Between(10000, 30000);
} else if (rand < 0.8) {
this.currentWeather = 'rain';
this.startRain(false);
this.maxWeatherDuration = Phaser.Math.Between(10000, 20000);
} else if (rand < 0.9) {
this.currentWeather = 'storm';
this.startRain(true);
this.maxWeatherDuration = Phaser.Math.Between(8000, 15000);
} else {
this.currentWeather = 'fog';
this.maxWeatherDuration = Phaser.Math.Between(10000, 20000);
}
this.weatherDuration = 0;
console.log(`Weather changed to: ${this.currentWeather}`);
}
setWeather(weather) {
this.currentWeather = weather;
this.weatherDuration = 0;
this.applyWeather();
startRain(heavy) {
const width = this.scene.scale.width;
const height = this.scene.scale.height;
const dropCount = heavy ? 150 : 100;
for (let i = 0; i < dropCount; i++) {
this.rainParticles.push({
x: Math.random() * width,
y: Math.random() * height,
speed: heavy ? Phaser.Math.Between(400, 600) : Phaser.Math.Between(200, 400),
length: heavy ? Phaser.Math.Between(10, 15) : Phaser.Math.Between(5, 10)
});
}
}
clearWeather() {
this.rainParticles = [];
}
// --- Getters for Other Systems ---
getCurrentHour() {
return Math.floor(this.gameTime);
}
getDayCount() {
return this.dayCount;
}
isNight() {
const hour = this.gameTime;
return hour >= 20 || hour < 5;
}
isDay() {
const hour = this.gameTime;
return hour >= 7 && hour < 18;
}
}