Bye
This commit is contained in:
parent
284ca6f64e
commit
82cfe5902f
@ -1,220 +0,0 @@
|
||||
<template>
|
||||
<Scene name="effects" @preload="preloadScene" @create="createScene" @update="updateScene" />
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import type { Map, WeatherState } from '@/application/types'
|
||||
import { MapStorage } from '@/storage/storages'
|
||||
import { useGameStore } from '@/stores/gameStore'
|
||||
import { useMapStore } from '@/stores/mapStore'
|
||||
import { Scene } from 'phavuer'
|
||||
import { onBeforeUnmount, onMounted, ref, watch } from 'vue'
|
||||
|
||||
// Types
|
||||
interface LightConfig {
|
||||
SUNRISE_HOUR: number
|
||||
SUNSET_HOUR: number
|
||||
DAY_STRENGTH: number
|
||||
NIGHT_STRENGTH: number
|
||||
TRANSITION_HOURS: number
|
||||
}
|
||||
|
||||
interface EffectObjects {
|
||||
light: Phaser.GameObjects.Graphics | null
|
||||
rain: Phaser.GameObjects.Particles.ParticleEmitter | null
|
||||
fog: Phaser.GameObjects.Sprite | null
|
||||
}
|
||||
|
||||
interface EffectValues {
|
||||
light?: number
|
||||
rain?: number
|
||||
fog?: number
|
||||
[key: string]: number | undefined
|
||||
}
|
||||
|
||||
// Constants
|
||||
const LIGHT_CONFIG: LightConfig = {
|
||||
SUNRISE_HOUR: 6,
|
||||
SUNSET_HOUR: 20,
|
||||
DAY_STRENGTH: 100,
|
||||
NIGHT_STRENGTH: 30,
|
||||
TRANSITION_HOURS: 3
|
||||
}
|
||||
|
||||
// Composables
|
||||
const useEffects = () => {
|
||||
const effects = ref<EffectObjects>({
|
||||
light: null,
|
||||
rain: null,
|
||||
fog: null
|
||||
})
|
||||
|
||||
const initializeEffects = (scene: Phaser.Scene) => {
|
||||
effects.value.light = scene.add.graphics().setDepth(1000)
|
||||
|
||||
effects.value.rain = 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'
|
||||
})
|
||||
.setDepth(900)
|
||||
effects.value.rain.stop()
|
||||
|
||||
effects.value.fog = scene.add
|
||||
.sprite(window.innerWidth / 2, window.innerHeight / 2, 'fog')
|
||||
.setScale(2)
|
||||
.setAlpha(0)
|
||||
.setDepth(950)
|
||||
}
|
||||
|
||||
const applyEffects = (effectValues: EffectValues) => {
|
||||
if (effects.value.light) {
|
||||
const darkness = 1 - (effectValues.light ?? 0) / 100
|
||||
effects.value.light.clear().fillStyle(0x000000, darkness).fillRect(0, 0, window.innerWidth, window.innerHeight)
|
||||
}
|
||||
|
||||
if (effects.value.rain) {
|
||||
if (effectValues.rain) {
|
||||
effects.value.rain.start().setQuantity(effectValues.rain / 10)
|
||||
} else {
|
||||
effects.value.rain.stop()
|
||||
}
|
||||
}
|
||||
|
||||
if (effects.value.fog && effectValues.fog !== undefined) {
|
||||
effects.value.fog.setAlpha(effectValues.fog / 100)
|
||||
}
|
||||
}
|
||||
|
||||
const handleResize = () => {
|
||||
if (effects.value.rain) {
|
||||
effects.value.rain.updateConfig({ x: { min: 0, max: window.innerWidth } })
|
||||
}
|
||||
if (effects.value.fog) {
|
||||
effects.value.fog.setPosition(window.innerWidth / 2, window.innerHeight / 2)
|
||||
}
|
||||
}
|
||||
|
||||
return { effects, initializeEffects, applyEffects, handleResize }
|
||||
}
|
||||
|
||||
// Store instances
|
||||
const gameStore = useGameStore()
|
||||
const mapStore = useMapStore()
|
||||
const mapStorage = new MapStorage()
|
||||
|
||||
// State
|
||||
const sceneRef = ref<Phaser.Scene | null>(null)
|
||||
const mapObject = ref<Map | null>(null)
|
||||
const weatherState = ref<WeatherState>({
|
||||
rainPercentage: 0,
|
||||
fogDensity: 0
|
||||
})
|
||||
|
||||
// Effects management
|
||||
const { effects, initializeEffects, applyEffects, handleResize } = useEffects()
|
||||
|
||||
// Utility functions
|
||||
const lerp = (x: number, y: number, a: number): number => x * (1 - a) + y * a
|
||||
|
||||
const calculateLightStrength = (time: Date): number => {
|
||||
const hour = time.getHours()
|
||||
const minute = time.getMinutes()
|
||||
|
||||
if (hour >= LIGHT_CONFIG.SUNSET_HOUR - LIGHT_CONFIG.TRANSITION_HOURS && hour < LIGHT_CONFIG.SUNSET_HOUR) {
|
||||
return lerp(LIGHT_CONFIG.DAY_STRENGTH, LIGHT_CONFIG.NIGHT_STRENGTH, (hour + minute / 60 - (LIGHT_CONFIG.SUNSET_HOUR - LIGHT_CONFIG.TRANSITION_HOURS)) / LIGHT_CONFIG.TRANSITION_HOURS)
|
||||
} else if (hour >= LIGHT_CONFIG.SUNRISE_HOUR && hour < LIGHT_CONFIG.SUNRISE_HOUR + LIGHT_CONFIG.TRANSITION_HOURS) {
|
||||
return lerp(LIGHT_CONFIG.NIGHT_STRENGTH, LIGHT_CONFIG.DAY_STRENGTH, (hour + minute / 60 - LIGHT_CONFIG.SUNRISE_HOUR) / LIGHT_CONFIG.TRANSITION_HOURS)
|
||||
} else if (hour > LIGHT_CONFIG.SUNRISE_HOUR && hour < LIGHT_CONFIG.SUNSET_HOUR) {
|
||||
return LIGHT_CONFIG.DAY_STRENGTH
|
||||
}
|
||||
return LIGHT_CONFIG.NIGHT_STRENGTH
|
||||
}
|
||||
|
||||
// Scene handlers
|
||||
const preloadScene = (scene: Phaser.Scene): void => {
|
||||
scene.load.image('raindrop', 'assets/raindrop.png')
|
||||
scene.load.image('fog', 'assets/fog.png')
|
||||
}
|
||||
|
||||
const createScene = (scene: Phaser.Scene): void => {
|
||||
sceneRef.value = scene
|
||||
initializeEffects(scene)
|
||||
setupSocketListeners()
|
||||
}
|
||||
|
||||
const updateScene = (): void => {
|
||||
const timeBasedLight = calculateLightStrength(gameStore.world.date)
|
||||
const mapEffects =
|
||||
mapObject.value?.mapEffects?.reduce<Record<string, number>>(
|
||||
(acc, curr) => ({
|
||||
...acc,
|
||||
[curr.effect]: curr.strength
|
||||
}),
|
||||
{}
|
||||
) ?? {}
|
||||
|
||||
const finalEffects: EffectValues = {
|
||||
...mapEffects,
|
||||
light: timeBasedLight,
|
||||
rain: weatherState.value.rainPercentage,
|
||||
fog: weatherState.value.fogDensity
|
||||
}
|
||||
|
||||
applyEffects(finalEffects)
|
||||
}
|
||||
|
||||
// Map management
|
||||
const loadMap = async (): Promise<void> => {
|
||||
if (!mapStore.mapId) return
|
||||
mapObject.value = await mapStorage.get(mapStore.mapId)
|
||||
}
|
||||
|
||||
// Socket handlers
|
||||
const setupSocketListeners = (): void => {
|
||||
gameStore.connection?.emit('weather', (response: WeatherState) => {
|
||||
weatherState.value = response
|
||||
updateScene()
|
||||
})
|
||||
|
||||
gameStore.connection?.on('weather', (data: WeatherState) => {
|
||||
weatherState.value = data
|
||||
updateScene()
|
||||
})
|
||||
|
||||
gameStore.connection?.on('date', updateScene)
|
||||
}
|
||||
|
||||
// Watchers
|
||||
watch(
|
||||
() => mapStore.mapId,
|
||||
async (newMapId) => {
|
||||
if (newMapId) {
|
||||
await loadMap()
|
||||
updateScene()
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
watch(
|
||||
() => mapObject.value,
|
||||
() => {
|
||||
updateScene()
|
||||
}
|
||||
)
|
||||
|
||||
// Lifecycle hooks
|
||||
onMounted(() => window.addEventListener('resize', handleResize))
|
||||
|
||||
onBeforeUnmount(() => {
|
||||
window.removeEventListener('resize', handleResize)
|
||||
if (sceneRef.value) sceneRef.value.scene.remove('effects')
|
||||
gameStore.connection?.off('weather')
|
||||
})
|
||||
</script>
|
@ -11,7 +11,6 @@
|
||||
<ExpBar />
|
||||
|
||||
<CharacterProfile />
|
||||
<Effects />
|
||||
</Scene>
|
||||
</Game>
|
||||
</div>
|
||||
@ -27,7 +26,6 @@ import ExpBar from '@/components/game/gui/ExpBar.vue'
|
||||
import Hotkeys from '@/components/game/gui/Hotkeys.vue'
|
||||
import Hud from '@/components/game/gui/Hud.vue'
|
||||
import Menu from '@/components/game/gui/Menu.vue'
|
||||
import Effects from '@/components/game/map/Effects.vue'
|
||||
import Map from '@/components/game/map/Map.vue'
|
||||
import { useGameStore } from '@/stores/gameStore'
|
||||
import { Game, Scene } from 'phavuer'
|
||||
|
Loading…
x
Reference in New Issue
Block a user