91 lines
2.9 KiB
Vue
91 lines
2.9 KiB
Vue
<template>
|
|
<MapTiles v-if="tileMap && tileMapLayer" :tileMap :tileMapLayer />
|
|
<PlacedMapObjects v-if="tileMap && tileMapLayer" :tileMap :tileMapLayer />
|
|
<Characters v-if="tileMap && mapStore.characters" :tileMap />
|
|
</template>
|
|
|
|
<script setup lang="ts">
|
|
import type { MapCharacter, mapLoadData, UUID } from '@/application/types'
|
|
import { unduplicateArray } from '@/application/utilities'
|
|
import Characters from '@/components/game/map/Characters.vue'
|
|
import MapTiles from '@/components/game/map/MapTiles.vue'
|
|
import PlacedMapObjects from '@/components/game/map/PlacedMapObjects.vue'
|
|
import { createTileLayer, createTileMap, loadTileTexturesFromMapTileArray } from '@/services/mapService'
|
|
import { MapStorage } from '@/storage/storages'
|
|
import { useGameStore } from '@/stores/gameStore'
|
|
import { useMapStore } from '@/stores/mapStore'
|
|
import { useScene } from 'phavuer'
|
|
import { onUnmounted, shallowRef, watch } from 'vue'
|
|
|
|
const scene = useScene()
|
|
|
|
const gameStore = useGameStore()
|
|
const mapStore = useMapStore()
|
|
|
|
const mapStorage = new MapStorage()
|
|
|
|
const tileMap = shallowRef<Phaser.Tilemaps.Tilemap>()
|
|
const tileMapLayer = shallowRef<Phaser.Tilemaps.TilemapLayer>()
|
|
|
|
// Event listeners
|
|
gameStore.connection?.on('map:character:teleport', async (data: mapLoadData) => {
|
|
mapStore.setMapId(data.mapId)
|
|
mapStore.setCharacters(data.characters)
|
|
})
|
|
|
|
gameStore.connection?.on('map:character:join', async (data: MapCharacter) => {
|
|
mapStore.addCharacter(data)
|
|
})
|
|
|
|
gameStore.connection?.on('map:character:leave', (characterId: UUID) => {
|
|
mapStore.removeCharacter(characterId)
|
|
})
|
|
|
|
gameStore.connection?.on('map:character:attack', (characterId: UUID) => {
|
|
mapStore.updateCharacterProperty(characterId, 'isAttacking', true)
|
|
})
|
|
|
|
gameStore.connection?.on('map:character:move', (data: { characterId: UUID; positionX: number; positionY: number; rotation: number; isMoving: boolean }) => {
|
|
mapStore.updateCharacterPosition(data)
|
|
// @TODO: Replace with universal class, composable or store
|
|
if (data.characterId === gameStore.character?.id) {
|
|
gameStore.character!.positionX = data.positionX
|
|
gameStore.character!.positionY = data.positionY
|
|
gameStore.character!.rotation = data.rotation
|
|
}
|
|
})
|
|
|
|
async function initialize() {
|
|
if (!mapStore.mapId) return
|
|
|
|
const map = await mapStorage.get(mapStore.mapId)
|
|
if (!map) return
|
|
|
|
await loadTileTexturesFromMapTileArray(mapStore.mapId, scene)
|
|
|
|
tileMap.value = createTileMap(scene, map)
|
|
tileMapLayer.value = createTileLayer(tileMap.value, unduplicateArray(map.tiles.flat()))
|
|
}
|
|
|
|
watch(
|
|
() => mapStore.mapId,
|
|
async () => {
|
|
await initialize()
|
|
}
|
|
)
|
|
|
|
onUnmounted(() => {
|
|
if (tileMap.value) {
|
|
tileMap.value.destroyLayer('tiles')
|
|
tileMap.value.removeAllLayers()
|
|
tileMap.value.destroy()
|
|
}
|
|
|
|
mapStore.reset()
|
|
gameStore.connection?.off('map:character:teleport')
|
|
gameStore.connection?.off('map:character:join')
|
|
gameStore.connection?.off('map:character:leave')
|
|
gameStore.connection?.off('map:character:move')
|
|
})
|
|
</script>
|