Merge remote-tracking branch 'origin/main' into feature/new-design-FE
This commit is contained in:
106
src/components/Effects.vue
Normal file
106
src/components/Effects.vue
Normal file
@ -0,0 +1,106 @@
|
||||
<template>
|
||||
<Scene name="effects" @preload="preloadScene" @create="createScene" @update="updateScene">
|
||||
</Scene>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { Scene } from 'phavuer'
|
||||
import { useGameStore } from '@/stores/gameStore'
|
||||
import { useZoneEditorStore } from '@/stores/zoneEditorStore'
|
||||
import { onBeforeMount, onBeforeUnmount, ref } from 'vue'
|
||||
|
||||
const gameStore = useGameStore()
|
||||
const zoneEditorStore = useZoneEditorStore()
|
||||
|
||||
// Effect-related refs
|
||||
const dayNightCycle = ref<Phaser.GameObjects.Graphics | null>(null)
|
||||
const rainEmitter = ref<Phaser.GameObjects.Particles.ParticleEmitter | null>(null)
|
||||
const fogSprite = ref<Phaser.GameObjects.Sprite | null>(null)
|
||||
|
||||
// Effect parameters
|
||||
const dayNightDuration = 300000 // 5 minutes in milliseconds
|
||||
const maxDarkness = 0.3
|
||||
|
||||
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) => {
|
||||
createDayNightCycle(scene)
|
||||
createRainEffect(scene)
|
||||
createFogEffect(scene)
|
||||
}
|
||||
|
||||
const updateScene = (scene: Phaser.Scene, time: number) => {
|
||||
updateDayNightCycle(time)
|
||||
updateFogEffect()
|
||||
}
|
||||
|
||||
const createDayNightCycle = (scene: Phaser.Scene) => {
|
||||
dayNightCycle.value = scene.add.graphics()
|
||||
dayNightCycle.value.setDepth(1000)
|
||||
}
|
||||
|
||||
const updateDayNightCycle = (time: number) => {
|
||||
if (!dayNightCycle.value) return
|
||||
|
||||
const darkness = Math.sin((time % dayNightDuration) / dayNightDuration * Math.PI) * maxDarkness
|
||||
dayNightCycle.value.clear()
|
||||
dayNightCycle.value.fillStyle(0x000000, darkness)
|
||||
dayNightCycle.value.fillRect(0, 0, window.innerWidth, window.innerHeight)
|
||||
}
|
||||
|
||||
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.1, end: 0.2 },
|
||||
alpha: { start: 0.5, end: 0 },
|
||||
blendMode: 'ADD'
|
||||
})
|
||||
rainEmitter.value.setDepth(900)
|
||||
toggleRain(false) // Start with rain off
|
||||
}
|
||||
|
||||
const toggleRain = (isRaining: boolean) => {
|
||||
if (rainEmitter.value) {
|
||||
rainEmitter.value.setVisible(isRaining)
|
||||
}
|
||||
}
|
||||
|
||||
const createFogEffect = (scene: Phaser.Scene) => {
|
||||
fogSprite.value = scene.add.sprite(window.width / 2, window.innerHeight / 2, 'fog')
|
||||
fogSprite.value.setScale(2)
|
||||
fogSprite.value.setAlpha(0)
|
||||
fogSprite.value.setDepth(950)
|
||||
}
|
||||
|
||||
const updateFogEffect = () => {
|
||||
if (fogSprite.value) {
|
||||
// Example: Oscillate fog opacity
|
||||
const fogOpacity = (Math.sin(Date.now() / 5000) + 1) / 2 * 0.3
|
||||
fogSprite.value.setAlpha(fogOpacity)
|
||||
}
|
||||
}
|
||||
|
||||
// Expose methods to control effects
|
||||
const controlEffects = {
|
||||
toggleRain,
|
||||
setFogDensity: (density: number) => {
|
||||
if (fogSprite.value) {
|
||||
fogSprite.value.setAlpha(density)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Make control methods available to parent components
|
||||
defineExpose(controlEffects)
|
||||
|
||||
onBeforeUnmount(() => {
|
||||
scene.destroy()
|
||||
})
|
||||
</script>
|
@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<Modal :is-modal-open="zoneEditorStore.isSettingsModalShown" @modal:close="() => zoneEditorStore.toggleSettingsModal()" :modal-width="300" :modal-height="350" :is-resizable="false">
|
||||
<Modal :is-modal-open="zoneEditorStore.isSettingsModalShown" @modal:close="() => zoneEditorStore.toggleSettingsModal()" :modal-width="600" :modal-height="350">
|
||||
<template #modalHeader>
|
||||
<h3 class="m-0 font-medium shrink-0 text-gray-300">Zone settings</h3>
|
||||
</template>
|
||||
|
@ -5,6 +5,7 @@
|
||||
|
||||
<div v-if="!zoneEditorStore.active">
|
||||
<Game :config="gameConfig" @create="createGame">
|
||||
<Effects />
|
||||
<Scene name="main" @preload="preloadScene" @create="createScene">
|
||||
<div v-if="isLoaded">
|
||||
<Inventory />
|
||||
@ -51,6 +52,7 @@ import ZoneEditor from '@/components/gameMaster/zoneEditor/ZoneEditor.vue'
|
||||
import GmPanel from '@/components/gameMaster/GmPanel.vue'
|
||||
import Inventory from '@/components/gui/UserPanel.vue'
|
||||
import { loadAssets } from '@/composables/zoneComposable'
|
||||
import Effects from '@/components/Effects.vue'
|
||||
|
||||
const gameStore = useGameStore()
|
||||
const zoneEditorStore = useZoneEditorStore()
|
||||
|
@ -1,8 +1,8 @@
|
||||
import { defineStore } from 'pinia'
|
||||
import { useGameStore } from '@/stores/gameStore'
|
||||
import type { Zone, Object, Tile, ZoneObject } from '@/types'
|
||||
import type { Zone, Object, Tile, ZoneObject, ZoneEffects } from '@/types'
|
||||
|
||||
type TeleportSettings = {
|
||||
export type TeleportSettings = {
|
||||
toZoneId: number
|
||||
toPositionX: number
|
||||
toPositionY: number
|
||||
@ -33,14 +33,15 @@ export const useZoneEditorStore = defineStore('zoneEditor', {
|
||||
name: '',
|
||||
width: 0,
|
||||
height: 0,
|
||||
pvp: false
|
||||
pvp: false,
|
||||
effects: [] as ZoneEffects[]
|
||||
},
|
||||
teleportSettings: {
|
||||
toZoneId: 0,
|
||||
toPositionX: 0,
|
||||
toPositionY: 0,
|
||||
toRotation: 0
|
||||
}
|
||||
} as TeleportSettings
|
||||
}
|
||||
},
|
||||
actions: {
|
||||
@ -66,6 +67,10 @@ export const useZoneEditorStore = defineStore('zoneEditor', {
|
||||
if (!this.zone) return
|
||||
this.zone.pvp = pvp
|
||||
},
|
||||
setZoneEffects(zoneEffects: ZoneEffects) {
|
||||
if (!this.zone) return
|
||||
this.zone.zoneEffects = zoneEffects
|
||||
},
|
||||
setTool(tool: string) {
|
||||
this.tool = tool
|
||||
},
|
||||
|
@ -53,6 +53,7 @@ export type Zone = {
|
||||
height: number
|
||||
tiles: any | null
|
||||
pvp: boolean
|
||||
zoneEffects: ZoneEffects
|
||||
zoneEventTiles: ZoneEventTile[]
|
||||
zoneObjects: ZoneObject[]
|
||||
characters: Character[]
|
||||
@ -61,6 +62,14 @@ export type Zone = {
|
||||
updatedAt: Date
|
||||
}
|
||||
|
||||
export type ZoneEffects = {
|
||||
id: string
|
||||
zoneId: number
|
||||
zone: Zone
|
||||
effect: string
|
||||
strength: number
|
||||
}
|
||||
|
||||
export type ZoneObject = {
|
||||
id: string
|
||||
zoneId: number
|
||||
|
Reference in New Issue
Block a user