1
0
forked from noxious/client

Overriding zone effects now works

This commit is contained in:
Dennis Postma 2024-12-07 22:50:27 +01:00
parent 8087f754b0
commit 857d56a878

View File

@ -10,24 +10,26 @@ import { onBeforeUnmount, onMounted, ref, watch } from 'vue'
import type { WeatherState } from '@/types' import type { WeatherState } from '@/types'
// Constants // Constants
const SUNRISE_HOUR = 6 const LIGHT_CONFIG = {
const SUNSET_HOUR = 20 SUNRISE_HOUR: 6,
const DAY_STRENGTH = 100 SUNSET_HOUR: 20,
const NIGHT_STRENGTH = 30 DAY_STRENGTH: 100,
NIGHT_STRENGTH: 30
}
// Stores // Stores and refs
const gameStore = useGameStore() const gameStore = useGameStore()
const zoneStore = useZoneStore() const zoneStore = useZoneStore()
// Scene ref
const sceneRef = ref<Phaser.Scene | null>(null) const sceneRef = ref<Phaser.Scene | null>(null)
// Effect refs // Effect objects
const lightEffect = ref<Phaser.GameObjects.Graphics | null>(null) const effects = {
const rainEmitter = ref<Phaser.GameObjects.Particles.ParticleEmitter | null>(null) light: ref<Phaser.GameObjects.Graphics | null>(null),
const fogSprite = ref<Phaser.GameObjects.Sprite | null>(null) rain: ref<Phaser.GameObjects.Particles.ParticleEmitter | null>(null),
fog: ref<Phaser.GameObjects.Sprite | null>(null)
}
// State refs // Weather state
const weatherState = ref<WeatherState>({ const weatherState = ref<WeatherState>({
isRainEnabled: false, isRainEnabled: false,
rainPercentage: 0, rainPercentage: 0,
@ -35,36 +37,24 @@ const weatherState = ref<WeatherState>({
fogDensity: 0 fogDensity: 0
}) })
// Scene lifecycle methods // Scene setup
const preloadScene = async (scene: Phaser.Scene) => { const preloadScene = (scene: Phaser.Scene) => {
scene.load.image('raindrop', 'assets/raindrop.png') scene.load.image('raindrop', 'assets/raindrop.png')
scene.load.image('fog', 'assets/fog.png') scene.load.image('fog', 'assets/fog.png')
} }
const createScene = async (scene: Phaser.Scene) => { const createScene = (scene: Phaser.Scene) => {
sceneRef.value = scene sceneRef.value = scene
setupEffects(scene) initializeEffects(scene)
setupSocketListeners() setupSocketListeners()
} }
const updateScene = () => { const initializeEffects = (scene: Phaser.Scene) => {
updateEffects() // Light
} effects.light.value = scene.add.graphics().setDepth(1000)
// Effect setup // Rain
const setupEffects = (scene: Phaser.Scene) => { effects.rain.value = scene.add.particles(0, 0, 'raindrop', {
createLightEffect(scene)
createRainEffect(scene)
createFogEffect(scene)
}
const createLightEffect = (scene: Phaser.Scene) => {
lightEffect.value = scene.add.graphics()
lightEffect.value.setDepth(1000)
}
const createRainEffect = (scene: Phaser.Scene) => {
rainEmitter.value = scene.add.particles(0, 0, 'raindrop', {
x: { min: 0, max: window.innerWidth }, x: { min: 0, max: window.innerWidth },
y: -50, y: -50,
quantity: 5, quantity: 5,
@ -73,145 +63,100 @@ const createRainEffect = (scene: Phaser.Scene) => {
scale: { start: 0.005, end: 0.005 }, scale: { start: 0.005, end: 0.005 },
alpha: { start: 0.5, end: 0 }, alpha: { start: 0.5, end: 0 },
blendMode: 'ADD' blendMode: 'ADD'
}).setDepth(900)
effects.rain.value.stop()
// Fog
effects.fog.value = scene.add.sprite(window.innerWidth / 2, window.innerHeight / 2, 'fog')
.setScale(2)
.setAlpha(0)
.setDepth(950)
}
// Effect updates
const updateScene = () => {
const timeBasedLight = calculateLightStrength(gameStore.world.date)
const zoneEffects = zoneStore.zone?.zoneEffects as Array<{ effect: string, strength: number }>
if (zoneEffects?.length) {
applyEffects({ light: timeBasedLight }, ...zoneEffects)
} else {
applyEffects({
light: timeBasedLight,
rain: weatherState.value.isRainEnabled ? weatherState.value.rainPercentage : 0,
fog: weatherState.value.isFogEnabled ? weatherState.value.fogDensity * 100 : 0
}) })
rainEmitter.value.setDepth(900) }
rainEmitter.value.stop()
} }
const createFogEffect = (scene: Phaser.Scene) => { const applyEffects = (effectValues: Record<string, number>) => {
fogSprite.value = scene.add.sprite(window.innerWidth / 2, window.innerHeight / 2, 'fog') if (effects.light.value) {
fogSprite.value.setScale(2) const darkness = 1 - (effectValues.light ?? 100) / 100
fogSprite.value.setAlpha(0) effects.light.value.clear()
fogSprite.value.setDepth(950) .fillStyle(0x000000, darkness)
.fillRect(0, 0, window.innerWidth, window.innerHeight)
}
if (effects.rain.value) {
const strength = effectValues.rain ?? 0
strength > 0
? effects.rain.value.start().setQuantity(Math.floor((strength / 100) * 10))
: effects.rain.value.stop()
}
if (effects.fog.value) {
effects.fog.value.setAlpha((effectValues.fog ?? 0) / 100)
}
} }
// Lighting calculations
const calculateLightStrength = (time: Date): number => { const calculateLightStrength = (time: Date): number => {
const hour = time.getHours() const hour = time.getHours()
const minute = time.getMinutes() const minute = time.getMinutes()
let strength = DAY_STRENGTH if (hour >= LIGHT_CONFIG.SUNSET_HOUR || hour < LIGHT_CONFIG.SUNRISE_HOUR)
return LIGHT_CONFIG.NIGHT_STRENGTH
// Night time (10 PM - 6 AM) if (hour > LIGHT_CONFIG.SUNRISE_HOUR && hour < LIGHT_CONFIG.SUNSET_HOUR - 2)
if (hour >= SUNSET_HOUR || hour < SUNRISE_HOUR) { return LIGHT_CONFIG.DAY_STRENGTH
strength = NIGHT_STRENGTH
}
// Full daylight (7 AM - 7 PM)
else if (hour > SUNRISE_HOUR && hour < SUNSET_HOUR - 2) {
strength = DAY_STRENGTH
}
// Sunrise transition (6 AM - 7 AM)
else if (hour === SUNRISE_HOUR) {
strength = NIGHT_STRENGTH + ((DAY_STRENGTH - NIGHT_STRENGTH) * minute) / 60
}
// Sunset transition (8 PM - 10 PM)
else if (hour >= SUNSET_HOUR - 2 && hour < SUNSET_HOUR) {
const totalMinutes = (hour - (SUNSET_HOUR - 2)) * 60 + minute
const transitionProgress = totalMinutes / 120 // 2 hours = 120 minutes
strength = DAY_STRENGTH - (DAY_STRENGTH - NIGHT_STRENGTH) * transitionProgress
}
return strength if (hour === LIGHT_CONFIG.SUNRISE_HOUR)
return LIGHT_CONFIG.NIGHT_STRENGTH +
((LIGHT_CONFIG.DAY_STRENGTH - LIGHT_CONFIG.NIGHT_STRENGTH) * minute) / 60
const totalMinutes = (hour - (LIGHT_CONFIG.SUNSET_HOUR - 2)) * 60 + minute
return LIGHT_CONFIG.DAY_STRENGTH -
(LIGHT_CONFIG.DAY_STRENGTH - LIGHT_CONFIG.NIGHT_STRENGTH) * (totalMinutes / 120)
} }
// Effect updates // Socket and window handlers
const updateEffects = () => {
const effects = zoneStore.zone?.zoneEffects || []
if (effects.length > 0) {
updateZoneEffects(effects)
} else {
// Make sure we're getting the current time
const lightStrength = calculateLightStrength(gameStore.world.date)
updateLightEffect(lightStrength)
updateWeatherEffects()
}
}
const updateZoneEffects = (effects: any[]) => {
// Always update light based on time when zone effects are present
updateLightEffect(calculateLightStrength(gameStore.world.date))
effects.forEach((effect) => {
switch (effect.effect) {
case 'rain':
updateRainEffect(effect.strength)
break
case 'fog':
updateFogEffect(effect.strength)
break
}
})
}
const updateWeatherEffects = () => {
updateRainEffect(weatherState.value.isRainEnabled ? weatherState.value.rainPercentage : 0)
updateFogEffect(weatherState.value.isFogEnabled ? weatherState.value.fogDensity * 100 : 0)
}
const updateLightEffect = (strength: number) => {
if (!lightEffect.value) return
const darkness = 1 - strength / 100
lightEffect.value.clear()
lightEffect.value.fillStyle(0x000000, darkness)
lightEffect.value.fillRect(0, 0, window.innerWidth, window.innerHeight)
}
const updateRainEffect = (strength: number) => {
if (!rainEmitter.value) return
if (strength > 0) {
rainEmitter.value.start()
rainEmitter.value.setQuantity(Math.floor((strength / 100) * 10))
} else {
rainEmitter.value.stop()
}
}
const updateFogEffect = (strength: number) => {
if (!fogSprite.value) return
fogSprite.value.setAlpha(strength / 100)
}
// Socket handlers
const setupSocketListeners = () => { const setupSocketListeners = () => {
// Initial weather state
gameStore.connection?.emit('weather', (response: WeatherState) => { gameStore.connection?.emit('weather', (response: WeatherState) => {
if (zoneStore.zone?.zoneEffects) return
weatherState.value = response weatherState.value = response
updateEffects() updateScene()
}) })
// Weather updates
gameStore.connection?.on('weather', (data: WeatherState) => { gameStore.connection?.on('weather', (data: WeatherState) => {
weatherState.value = data weatherState.value = data
updateEffects() updateScene()
}) })
// Time updates gameStore.connection?.on('date', updateScene)
gameStore.connection?.on('date', () => {
if (zoneStore.zone?.zoneEffects) return
updateEffects()
})
} }
const updateEffectWindowSize = () => { const handleResize = () => {
if (rainEmitter.value) rainEmitter.value.updateConfig({ x: { min: 0, max: window.innerWidth } }) if (effects.rain.value)
if (fogSprite.value) { effects.rain.value.updateConfig({ x: { min: 0, max: window.innerWidth } })
fogSprite.value.setX(window.innerWidth / 2) if (effects.fog.value)
fogSprite.value.setY(window.innerHeight / 2) effects.fog.value.setPosition(window.innerWidth / 2, window.innerHeight / 2)
}
} }
// Watchers // Lifecycle
watch(() => zoneStore.zone?.zoneEffects, updateEffects, { deep: true }) watch(() => zoneStore.zone?.zoneEffects, updateScene, { deep: true })
onMounted(() => { onMounted(() => window.addEventListener('resize', handleResize))
window.addEventListener('resize', updateEffectWindowSize)
})
// Cleanup
onBeforeUnmount(() => { onBeforeUnmount(() => {
window.removeEventListener('resize', updateEffectWindowSize) window.removeEventListener('resize', handleResize)
if (sceneRef.value) sceneRef.value.scene.remove('effects') if (sceneRef.value) sceneRef.value.scene.remove('effects')
gameStore.connection?.off('weather') gameStore.connection?.off('weather')
}) })