diff --git a/index.html b/index.html
index caf68e9..0f56940 100644
--- a/index.html
+++ b/index.html
@@ -71,14 +71,14 @@
-
+
-
+
diff --git a/src/scenes/GameScene.js b/src/scenes/GameScene.js
index 9dfc2f3..795f4dc 100644
--- a/src/scenes/GameScene.js
+++ b/src/scenes/GameScene.js
@@ -87,9 +87,10 @@ class GameScene extends Phaser.Scene {
this.setupCamera();
// Initialize Time & Stats
- console.log('⏳ Initializing Time & Stats...');
- this.timeSystem = new TimeSystem(this);
- this.timeSystem.create();
+ // Initialize Weather System (Unified: Time + DayNight + Weather)
+ console.log('🌦️ Initializing Unified Weather System...');
+ this.weatherSystem = new WeatherSystem(this);
+ this.timeSystem = this.weatherSystem; // Alias for compatibility with other systems (e.g. UIScene, Farming)
this.statsSystem = new StatsSystem(this);
this.inventorySystem = new InventorySystem(this);
@@ -97,13 +98,7 @@ class GameScene extends Phaser.Scene {
this.farmingSystem = new FarmingSystem(this);
this.buildingSystem = new BuildingSystem(this);
- // Initialize Weather System
- console.log('🌦️ Initializing Weather System...');
- this.weatherSystem = new WeatherSystem(this);
-
- // Initialize Day/Night Cycle
- console.log('🌅 Initializing Day/Night System...');
- this.dayNightSystem = new DayNightSystem(this, this.timeSystem);
+ // DayNightSystem removed (merged into WeatherSystem)
// Initialize Sound Manager
console.log('🎵 Initializing Sound Manager...');
@@ -198,11 +193,11 @@ class GameScene extends Phaser.Scene {
update(time, delta) {
// Update Systems
- if (this.timeSystem) this.timeSystem.update(delta);
+ // TimeSystem update removed (handled by WeatherSystem)
if (this.statsSystem) this.statsSystem.update(delta);
if (this.interactionSystem) this.interactionSystem.update(delta);
if (this.farmingSystem) this.farmingSystem.update(delta);
- if (this.dayNightSystem) this.dayNightSystem.update();
+ // DayNight update removed (handled by WeatherSystem)
if (this.weatherSystem) this.weatherSystem.update(delta);
// Update Parallax (foreground grass fading)
diff --git a/src/systems/DayNightSystem.js b/src/systems/DayNightSystem.js
deleted file mode 100644
index a71c908..0000000
--- a/src/systems/DayNightSystem.js
+++ /dev/null
@@ -1,95 +0,0 @@
-class DayNightSystem {
- constructor(scene, timeSystem) {
- this.scene = scene;
- this.timeSystem = timeSystem;
-
- // Visual overlay
- this.overlay = null;
- this.currentPhase = 'day'; // dawn, day, dusk, night
-
- this.init();
- }
-
- init() {
- // No local overlay - using UIScene.overlayGraphics
- }
-
- update() {
- if (!this.timeSystem) return;
-
- const hour = this.timeSystem.getCurrentHour();
- const phase = this.getPhase(hour);
-
- if (phase !== this.currentPhase) {
- this.currentPhase = phase;
- console.log(`🌅 Time of Day: ${phase} (${hour}:00)`);
- }
-
- this.updateLighting(hour);
- }
-
- 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';
- }
-
- updateLighting(hour) {
- // Get Shared Overlay from UI Scene
- const uiScene = this.scene.scene.get('UIScene');
- if (!uiScene || !uiScene.overlayGraphics) return;
-
- const graphics = uiScene.overlayGraphics;
-
- // IMPORTANT: DayNight is the FIRST system to render to overlay, so it MUST CLEAR it.
- graphics.clear();
-
- const width = uiScene.scale.width;
- const height = uiScene.scale.height;
-
- let color = 0x000033; // Default night blue
- let alpha = 0;
-
- if (hour >= 0 && hour < 5) {
- // Deep Night (0-5h) - Dark blue
- color = 0x000033;
- alpha = 0.6;
- } else if (hour >= 5 && hour < 7) {
- // Dawn (5-7h) - Orange/Pink gradient
- color = 0xFF6B35;
- const progress = (hour - 5) / 2; // 0-1
- alpha = 0.6 - (progress * 0.6); // 0.6 -> 0
- } else if (hour >= 7 && hour < 18) {
- // Day (7-18h) - No overlay (bright)
- alpha = 0;
- } else if (hour >= 18 && hour < 20) {
- // Dusk (18-20h) - Orange/Purple
- color = 0x8B4789;
- const progress = (hour - 18) / 2; // 0-1
- alpha = progress * 0.5; // 0 -> 0.5
- } else if (hour >= 20 && hour < 24) {
- // Night (20-24h) - Dark blue
- color = 0x000033;
- const progress = (hour - 20) / 4; // 0-1
- alpha = 0.5 + (progress * 0.1); // 0.5 -> 0.6
- }
-
- if (alpha > 0) {
- graphics.fillStyle(color, alpha);
- graphics.fillRect(0, 0, width, height);
- }
- }
-
- getCurrentPhase() {
- return this.currentPhase;
- }
-
- isNight() {
- return this.currentPhase === 'night';
- }
-
- isDay() {
- return this.currentPhase === 'day';
- }
-}
diff --git a/src/systems/TimeSystem.js b/src/systems/TimeSystem.js
deleted file mode 100644
index 99a7282..0000000
--- a/src/systems/TimeSystem.js
+++ /dev/null
@@ -1,107 +0,0 @@
-class TimeSystem {
- constructor(scene) {
- this.scene = scene;
-
- // Konfiguracija
- this.fullDaySeconds = 300; // 5 minut za cel dan (real-time)
- this.startTime = 8; // Začetek ob 8:00
-
- // Stanje
- this.gameTime = this.startTime; // 0 - 24
- this.dayCount = 1;
-
- // Lighting overlay
- this.lightOverlay = null; // Ustvarjen bo v GameScene ali tu? Bolje tu če imamo dostop.
- }
-
- create() {
- // Overlay za temo
- // Uporabimo velik pravokotnik čez cel ekran, ki je fixiran na kamero
- // Ampak ker imamo UIScene, je bolje da je overlay v GameScene, ampak nad vsem razen UI.
- // Najlažje: canvas tinting ali graphics overlay.
-
- // Za preprostost: Modificiramo ambient light ali tintamo igralca/teren?
- // Phaser 3 ima setTint.
- // Najboljši efekt za 2D: Temno moder rectangle z 'MULTIPLY' blend mode čez GameScene.
-
- const width = this.scene.cameras.main.width * 2; // Malo večji za varnost
- const height = this.scene.cameras.main.height * 2;
-
- this.lightOverlay = this.scene.add.rectangle(0, 0, width, height, 0x000022);
- this.lightOverlay.setScrollFactor(0);
- this.lightOverlay.setDepth(9000); // Pod UI (UI je v drugi sceni), ampak nad igro
- this.lightOverlay.setBlendMode(Phaser.BlendModes.MULTIPLY);
- this.lightOverlay.setAlpha(0); // Začetek dan (0 alpha)
- }
-
- update(delta) {
- // Povečaj čas
- // delta je v ms.
- // fullDaySeconds = 24 game hours.
- // 1 game hour = fullDaySeconds / 24 seconds.
- 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!`);
- }
-
- this.updateLighting();
- this.updateUI();
- }
-
- updateLighting() {
- if (!this.lightOverlay) return;
-
- // Izračunaj svetlobo (Alpha vrednost senc)
- // 0 = Dan (Prozoren overlay)
- // 0.8 = Polnoč (Temen overlay)
-
- let alpha = 0;
- const t = this.gameTime;
-
- // Preprosta logika:
- // 6:00 - 18:00 = Dan (0 alpha)
- // 18:00 - 20:00 = Mrak (prehod 0 -> 0.7)
- // 20:00 - 4:00 = Noč (0.7 alpha)
- // 4:00 - 6:00 = Jutro (prehod 0.7 -> 0)
-
- if (t >= 6 && t < 18) {
- alpha = 0; // Dan
- } else if (t >= 18 && t < 20) {
- alpha = ((t - 18) / 2) * 0.7; // Mrak
- } else if (t >= 20 || t < 4) {
- alpha = 0.7; // Noč
- } else if (t >= 4 && t < 6) {
- alpha = 0.7 - ((t - 4) / 2) * 0.7; // Jutro
- }
-
- this.lightOverlay.setAlpha(alpha);
- }
-
- updateUI() {
- 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}`);
- }
- }
-
- getCurrentHour() {
- return Math.floor(this.gameTime);
- }
-
- getGameTime() {
- return this.gameTime;
- }
-
- getDayCount() {
- return this.dayCount;
- }
-}
diff --git a/src/systems/WeatherSystem.js b/src/systems/WeatherSystem.js
index a50c757..283e32d 100644
--- a/src/systems/WeatherSystem.js
+++ b/src/systems/WeatherSystem.js
@@ -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;
}
}