1
0
forked from noxious/client

TS improvements, WIP loading map objects in game map, WIP loading tile textures

This commit is contained in:
Dennis Postma 2025-02-05 00:47:28 +01:00
parent 2b40741ca7
commit 027fdd7dac
9 changed files with 57 additions and 40 deletions

View File

@ -20,7 +20,7 @@ import { Container, Sprite, useScene } from 'phavuer'
import { onMounted, onUnmounted, watch } from 'vue' import { onMounted, onUnmounted, watch } from 'vue'
const props = defineProps<{ const props = defineProps<{
tilemap: Phaser.Tilemaps.Tilemap tileMap: Phaser.Tilemaps.Tilemap
mapCharacter: MapCharacter mapCharacter: MapCharacter
}>() }>()
@ -28,7 +28,7 @@ const gameStore = useGameStore()
const mapStore = useMapStore() const mapStore = useMapStore()
const scene = useScene() const scene = useScene()
const { characterContainer, characterSprite, currentPositionX, currentPositionY, isometricDepth, isFlippedX, updatePosition, calcDirection, updateSprite, initializeSprite, cleanup } = useCharacterSpriteComposable(scene, props.tilemap, props.mapCharacter) const { characterContainer, characterSprite, currentPositionX, currentPositionY, isometricDepth, isFlippedX, updatePosition, calcDirection, updateSprite, initializeSprite, cleanup } = useCharacterSpriteComposable(scene, props.tileMap, props.mapCharacter)
const handlePositionUpdate = (newValues: any, oldValues: any) => { const handlePositionUpdate = (newValues: any, oldValues: any) => {
if (!newValues) return if (!newValues) return

View File

@ -1,5 +1,5 @@
<template> <template>
<Character v-for="item in mapStore.characters" :key="item.character.id" :tilemap="tilemap" :mapCharacter="item" /> <Character v-for="item in mapStore.characters" :key="item.character.id" :tileMap :mapCharacter="item" />
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
@ -9,6 +9,6 @@ import { useMapStore } from '@/stores/mapStore'
const mapStore = useMapStore() const mapStore = useMapStore()
const props = defineProps<{ const props = defineProps<{
tilemap: Phaser.Tilemaps.Tilemap tileMap: Phaser.Tilemaps.Tilemap
}>() }>()
</script> </script>

View File

@ -1,7 +1,7 @@
<template> <template>
<MapTiles :key="mapStore.mapId" @tileMap:create="tileMap = $event" /> <MapTiles :key="mapStore.mapId" :tileMap :tileMapLayer />
<PlacedMapObjects v-if="tileMap" :key="mapStore.mapId" :tilemap="tileMap" /> <PlacedMapObjects v-if="tileMap" :key="mapStore.mapId" :tileMap :tileMapLayer />
<Characters v-if="tileMap && mapStore.characters" :tilemap="tileMap" /> <Characters v-if="tileMap && mapStore.characters" :tileMap />
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
@ -11,12 +11,20 @@ import MapTiles from '@/components/game/map/MapTiles.vue'
import PlacedMapObjects from '@/components/game/map/PlacedMapObjects.vue' import PlacedMapObjects from '@/components/game/map/PlacedMapObjects.vue'
import { useGameStore } from '@/stores/gameStore' import { useGameStore } from '@/stores/gameStore'
import { useMapStore } from '@/stores/mapStore' import { useMapStore } from '@/stores/mapStore'
import { onUnmounted, shallowRef } from 'vue' import { onMounted, onUnmounted, shallowRef } from 'vue'
import { createTileLayer, createTileMap } from '@/services/mapService'
import { useScene } from 'phavuer'
import { MapStorage } from '@/storage/storages'
const scene = useScene()
const gameStore = useGameStore() const gameStore = useGameStore()
const mapStore = useMapStore() const mapStore = useMapStore()
const mapStorage = new MapStorage()
const tileMap = shallowRef<Phaser.Tilemaps.Tilemap>() const tileMap = shallowRef<Phaser.Tilemaps.Tilemap>()
const tileMapLayer = shallowRef<Phaser.Tilemaps.TilemapLayer>()
// Event listeners // Event listeners
gameStore.connection?.on('map:character:teleport', async (data: mapLoadData) => { gameStore.connection?.on('map:character:teleport', async (data: mapLoadData) => {
@ -46,6 +54,16 @@ gameStore.connection?.on('map:character:move', (data: { characterId: UUID; posit
} }
}) })
onMounted(async () => {
if (!mapStore.mapId) return
const map = await mapStorage.get(mapStore.mapId)
if (!map) return
tileMap.value = createTileMap(scene, map)
tileMapLayer.value = createTileLayer(tileMap.value, map)
})
onUnmounted(() => { onUnmounted(() => {
mapStore.reset() mapStore.reset()
gameStore.connection?.off('map:character:teleport') gameStore.connection?.off('map:character:teleport')

View File

@ -1,39 +1,38 @@
<template> <template>
<Controls v-if="tileLayer" :layer="tileLayer" :depth="0" /> <Controls v-if="tileMapLayer" :layer="tileMapLayer" :depth="0" />
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import type { UUID } from '@/application/types' import type { UUID } from '@/application/types'
import Controls from '@/components/utilities/Controls.vue' import Controls from '@/components/utilities/Controls.vue'
import { createTileLayer, createTileMap, loadTileTexturesFromMapTileArray, setLayerTiles } from '@/services/mapService' import { loadTileTexturesFromMapTileArray, placeTiles } from '@/services/mapService'
import { MapStorage } from '@/storage/storages' import { MapStorage } from '@/storage/storages'
import { useMapStore } from '@/stores/mapStore' import { useMapStore } from '@/stores/mapStore'
import { useScene } from 'phavuer' import { useScene } from 'phavuer'
import { onBeforeUnmount, shallowRef } from 'vue' import { onMounted } from 'vue'
const emit = defineEmits(['tileMap:create'])
const scene = useScene() const scene = useScene()
const mapStore = useMapStore() const mapStore = useMapStore()
const mapStorage = new MapStorage() const mapStorage = new MapStorage()
const tileMap = shallowRef<Phaser.Tilemaps.Tilemap>() const props = defineProps<{
const tileLayer = shallowRef<Phaser.Tilemaps.TilemapLayer>() tileMap: Phaser.Tilemaps.Tilemap
tileMapLayer: Phaser.Tilemaps.TilemapLayer
}>()
loadTileTexturesFromMapTileArray(mapStore.mapId as UUID, scene) loadTileTexturesFromMapTileArray(mapStore.mapId as UUID, scene)
.then(() => mapStorage.get(mapStore.mapId)) .then(() => mapStorage.get(mapStore.mapId))
.then((mapData) => { .then((mapData) => {
if (!mapData || !mapData?.tiles) return if (!mapData || !mapData?.tiles) return
tileMap.value = createTileMap(scene, mapData)
emit('tileMap:create', tileMap.value)
tileLayer.value = createTileLayer(tileMap.value, mapData)
setLayerTiles(tileMap.value, tileLayer.value, mapData.tiles)
}) })
.catch((error) => console.error('Failed to initialize map:', error)) .catch((error) => console.error('Failed to initialize map:', error))
onBeforeUnmount(() => { onMounted(async () => {
if (!tileMap.value) return if (!mapStore.mapId) return
tileMap.value.destroyLayer('tiles')
tileMap.value.removeAllLayers() const map = await mapStorage.get(mapStore.mapId)
tileMap.value.destroy() if (!map) return
placeTiles(props.tileMap, props.tileMapLayer, map.tiles)
}) })
</script> </script>

View File

@ -1,5 +1,5 @@
<template> <template>
<PlacedMapObject v-for="placedMapObject in items" :tilemap="tilemap" :placedMapObject /> <PlacedMapObject v-for="placedMapObject in items" :tileMap :tileMapLayer :placedMapObject />
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
@ -8,9 +8,11 @@ import PlacedMapObject from '@/components/game/map/partials/PlacedMapObject.vue'
import { MapStorage } from '@/storage/storages' import { MapStorage } from '@/storage/storages'
import { useMapStore } from '@/stores/mapStore' import { useMapStore } from '@/stores/mapStore'
import { onMounted, ref } from 'vue' import { onMounted, ref } from 'vue'
import TilemapLayer = Phaser.Tilemaps.TilemapLayer
defineProps<{ defineProps<{
tilemap: Phaser.Tilemaps.Tilemap tileMap: Phaser.Tilemaps.Tilemap
tileMapLayer: TilemapLayer
}>() }>()
const mapStore = useMapStore() const mapStore = useMapStore()

View File

@ -1,6 +1,6 @@
<template> <template>
<MapTiles ref="mapTiles" v-if="tileMap" :tileMapLayer :tileMap @tileMap:create="tileMap = $event" /> <MapTiles ref="mapTiles" v-if="tileMap" :tileMap :tileMapLayer />
<PlacedMapObjects ref="mapObjects" v-if="tileMap" :tileMapLayer :tileMap /> <PlacedMapObjects ref="mapObjects" v-if="tileMap" :tileMap :tileMapLayer />
<MapEventTiles ref="eventTiles" v-if="tileMap" :tileMap /> <MapEventTiles ref="eventTiles" v-if="tileMap" :tileMap />
</template> </template>
@ -78,7 +78,6 @@ onMounted(() => {
let mapValue = mapEditor.currentMap.value let mapValue = mapEditor.currentMap.value
if (!mapValue) return if (!mapValue) return
tileMap.value = createTileMap(scene, mapValue) tileMap.value = createTileMap(scene, mapValue)
mapTiles.value?.$emit('tileMap:create', tileMap.value)
tileMapLayer.value = createTileLayer(tileMap.value, mapValue) tileMapLayer.value = createTileLayer(tileMap.value, mapValue)
addEventListener('keydown', handleKeyDown) addEventListener('keydown', handleKeyDown)

View File

@ -1,15 +1,13 @@
<template> <template>
<Controls v-if="props.tileMapLayer" :layer="props.tileMapLayer" :depth="0" /> <Controls v-if="tileMapLayer" :layer="tileMapLayer" :depth="0" />
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import Controls from '@/components/utilities/Controls.vue' import Controls from '@/components/utilities/Controls.vue'
import { useMapEditorComposable } from '@/composables/useMapEditorComposable' import { useMapEditorComposable } from '@/composables/useMapEditorComposable'
import { createTileArray, getTile, placeTile, setLayerTiles } from '@/services/mapService' import { createTileArray, getTile, placeTile, placeTiles } from '@/services/mapService'
import { useScene } from 'phavuer'
import { onMounted, ref, watch } from 'vue' import { onMounted, ref, watch } from 'vue'
const emit = defineEmits(['tileMap:create'])
const mapEditor = useMapEditorComposable() const mapEditor = useMapEditorComposable()
defineExpose({ handlePointer, finalizeCommand, undo, redo }) defineExpose({ handlePointer, finalizeCommand, undo, redo })
@ -80,7 +78,7 @@ function paint(pointer: Phaser.Input.Pointer) {
// Set new tileArray with selected tile // Set new tileArray with selected tile
const tileArray = createTileArray(props.tileMap.width, props.tileMap.height, mapEditor.selectedTile.value) const tileArray = createTileArray(props.tileMap.width, props.tileMap.height, mapEditor.selectedTile.value)
setLayerTiles(props.tileMap, props.tileMapLayer, tileArray) placeTiles(props.tileMap, props.tileMapLayer, tileArray)
// Adjust mapEditorStore.map.tiles // Adjust mapEditorStore.map.tiles
map.tiles = tileArray map.tiles = tileArray
@ -182,7 +180,7 @@ function updateMapTiles() {
let indexedCommands = commandStack.slice(0, commandIndex.value) let indexedCommands = commandStack.slice(0, commandIndex.value)
let modifiedTiles = applyCommands(originTiles, ...indexedCommands) let modifiedTiles = applyCommands(originTiles, ...indexedCommands)
setLayerTiles(props.tileMap, props.tileMapLayer, modifiedTiles) placeTiles(props.tileMap, props.tileMapLayer, modifiedTiles)
mapEditor.currentMap.value.tiles = modifiedTiles mapEditor.currentMap.value.tiles = modifiedTiles
} }
@ -196,7 +194,7 @@ watch(
(shouldClear) => { (shouldClear) => {
if (shouldClear && mapEditor.currentMap.value) { if (shouldClear && mapEditor.currentMap.value) {
const blankTiles = createTileArray(props.tileMapLayer.width, props.tileMapLayer.height, 'blank_tile') const blankTiles = createTileArray(props.tileMapLayer.width, props.tileMapLayer.height, 'blank_tile')
setLayerTiles(props.tileMap, props.tileMapLayer, blankTiles) placeTiles(props.tileMap, props.tileMapLayer, blankTiles)
mapEditor.currentMap.value.tiles = blankTiles mapEditor.currentMap.value.tiles = blankTiles
mapEditor.resetClearTilesFlag() mapEditor.resetClearTilesFlag()
} }
@ -210,6 +208,6 @@ onMounted(async () => {
//Clone //Clone
originTiles = cloneArray(mapState.tiles) originTiles = cloneArray(mapState.tiles)
setLayerTiles(props.tileMap, props.tileMapLayer, mapState.tiles) placeTiles(props.tileMap, props.tileMapLayer, mapState.tiles)
}) })
</script> </script>

View File

@ -1,6 +1,6 @@
<template> <template>
<SelectedPlacedMapObjectComponent v-if="mapEditor.selectedPlacedObject.value" :placedMapObject="mapEditor.selectedPlacedObject.value" @move="moveMapObject" @rotate="rotatePlacedMapObject" @delete="deletePlacedMapObject" /> <SelectedPlacedMapObjectComponent v-if="mapEditor.selectedPlacedObject.value" :placedMapObject="mapEditor.selectedPlacedObject.value" @move="moveMapObject" @rotate="rotatePlacedMapObject" @delete="deletePlacedMapObject" />
<PlacedMapObject :tileMapLayer :tileMap v-for="placedMapObject in mapEditor.currentMap.value?.placedMapObjects" :placedMapObject @pointerdown="clickPlacedMapObject(placedMapObject)" /> <PlacedMapObject v-for="placedMapObject in mapEditor.currentMap.value?.placedMapObjects" :tileMap :tileMapLayer :placedMapObject @pointerdown="clickPlacedMapObject(placedMapObject)" />
</template> </template>
<script setup lang="ts"> <script setup lang="ts">

View File

@ -53,8 +53,8 @@ export function placeTile(map: Tilemap, layer: TilemapLayer, positionX: number,
layer.putTileAt(tileImg.firstgid, positionX, positionY) layer.putTileAt(tileImg.firstgid, positionX, positionY)
} }
export function setLayerTiles(map: Tilemap, layer: TilemapLayer, tiles: string[][]) { export function placeTiles(map: Tilemap, layer: TilemapLayer, tiles: string[][]) {
if (!tiles) return if (!map || !layer || !tiles) return
tiles.forEach((row: string[], y: number) => { tiles.forEach((row: string[], y: number) => {
row.forEach((tile: string, x: number) => { row.forEach((tile: string, x: number) => {
@ -113,6 +113,7 @@ export async function loadAllTileTextures(scene: Phaser.Scene) {
const tiles = await tileStorage.getAll() const tiles = await tileStorage.getAll()
await loadTileTextures(tiles, scene) await loadTileTextures(tiles, scene)
scene.load.start()
} }
export function createTileMap(scene: Phaser.Scene, map: MapT) { export function createTileMap(scene: Phaser.Scene, map: MapT) {
@ -128,7 +129,7 @@ export function createTileMap(scene: Phaser.Scene, map: MapT) {
return new Phaser.Tilemaps.Tilemap(scene, mapConfig) return new Phaser.Tilemaps.Tilemap(scene, mapConfig)
} }
export function createTileLayer(currentTileMap: Phaser.Tilemaps.Tilemap, mapData: any) { export function createTileLayer(currentTileMap: Phaser.Tilemaps.Tilemap, mapData: MapT) {
const tilesArray = unduplicateArray(mapData?.tiles.flat()) const tilesArray = unduplicateArray(mapData?.tiles.flat())
const tilesetImages = tilesArray.map((tile: string, index: number) => { const tilesetImages = tilesArray.map((tile: string, index: number) => {