združen time in weather
This commit is contained in:
@@ -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)
|
||||
|
||||
@@ -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';
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user