forked from noxious/client
111 lines
2.9 KiB
Vue
111 lines
2.9 KiB
Vue
<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>
|