<template> <Scene name="effects" @preload="preloadScene" @create="createScene" @update="updateScene"> </Scene> </template> <script setup lang="ts"> import { Scene } from 'phavuer' import { useZoneStore } from '@/stores/zoneStore' import { onBeforeUnmount, ref, watch } from 'vue' const zoneStore = useZoneStore() const sceneRef = ref<Phaser.Scene | null>(null) // Effect-related refs const lightEffect = ref<Phaser.GameObjects.Graphics | null>(null) const rainEmitter = ref<Phaser.GameObjects.Particles.ParticleEmitter | null>(null) const fogSprite = ref<Phaser.GameObjects.Sprite | null>(null) const preloadScene = async (scene: Phaser.Scene) => { scene.load.image('raindrop', 'assets/raindrop.png') scene.load.image('fog', 'assets/fog.png') } const createScene = async (scene: Phaser.Scene) => { sceneRef.value = scene createLightEffect(scene) createRainEffect(scene) createFogEffect(scene) } const updateScene = () => { updateEffects() } 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 }, y: -50, quantity: 5, lifespan: 2000, speedY: { min: 300, max: 500 }, scale: { start: 0.005, end: 0.005 }, alpha: { start: 0.5, end: 0 }, blendMode: 'ADD' }) rainEmitter.value.setDepth(900) rainEmitter.value.stop() } const createFogEffect = (scene: Phaser.Scene) => { fogSprite.value = scene.add.sprite(window.innerWidth / 2, window.innerHeight / 2, 'fog') fogSprite.value.setScale(2) fogSprite.value.setAlpha(0) fogSprite.value.setDepth(950) } const updateEffects = () => { const effects = zoneStore.zone?.zoneEffects || [] effects.forEach((effect) => { switch (effect.effect) { case 'light': updateLightEffect(effect.strength) break case 'rain': updateRainEffect(effect.strength) break case 'fog': updateFogEffect(effect.strength) break } }) } 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) } watch(() => zoneStore.zone?.zoneEffects, updateEffects, { deep: true }) onBeforeUnmount(() => { if (sceneRef.value) sceneRef.value.scene.remove('effects') }) // @TODO : Fix resize issue </script>