From 027fdd7dac3b6f24fd499ec01c18f59b5dda26c5 Mon Sep 17 00:00:00 2001
From: Dennis Postma <dennis@directonline.io>
Date: Wed, 5 Feb 2025 00:47:28 +0100
Subject: [PATCH] TS improvements, WIP loading map objects in game map, WIP
 loading tile textures

---
 src/components/game/character/Character.vue   |  4 +--
 src/components/game/map/Characters.vue        |  4 +--
 src/components/game/map/Map.vue               | 26 ++++++++++++++---
 src/components/game/map/MapTiles.vue          | 29 +++++++++----------
 src/components/game/map/PlacedMapObjects.vue  |  6 ++--
 src/components/gameMaster/mapEditor/Map.vue   |  5 ++--
 .../mapEditor/mapPartials/MapTiles.vue        | 14 ++++-----
 .../mapPartials/PlacedMapObjects.vue          |  2 +-
 src/services/mapService.ts                    |  7 +++--
 9 files changed, 57 insertions(+), 40 deletions(-)

diff --git a/src/components/game/character/Character.vue b/src/components/game/character/Character.vue
index 0db7e60..795e0c5 100644
--- a/src/components/game/character/Character.vue
+++ b/src/components/game/character/Character.vue
@@ -20,7 +20,7 @@ import { Container, Sprite, useScene } from 'phavuer'
 import { onMounted, onUnmounted, watch } from 'vue'
 
 const props = defineProps<{
-  tilemap: Phaser.Tilemaps.Tilemap
+  tileMap: Phaser.Tilemaps.Tilemap
   mapCharacter: MapCharacter
 }>()
 
@@ -28,7 +28,7 @@ const gameStore = useGameStore()
 const mapStore = useMapStore()
 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) => {
   if (!newValues) return
diff --git a/src/components/game/map/Characters.vue b/src/components/game/map/Characters.vue
index 669c0e8..3f9172c 100644
--- a/src/components/game/map/Characters.vue
+++ b/src/components/game/map/Characters.vue
@@ -1,5 +1,5 @@
 <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>
 
 <script setup lang="ts">
@@ -9,6 +9,6 @@ import { useMapStore } from '@/stores/mapStore'
 const mapStore = useMapStore()
 
 const props = defineProps<{
-  tilemap: Phaser.Tilemaps.Tilemap
+  tileMap: Phaser.Tilemaps.Tilemap
 }>()
 </script>
diff --git a/src/components/game/map/Map.vue b/src/components/game/map/Map.vue
index da80c68..8e28e27 100644
--- a/src/components/game/map/Map.vue
+++ b/src/components/game/map/Map.vue
@@ -1,7 +1,7 @@
 <template>
-  <MapTiles :key="mapStore.mapId" @tileMap:create="tileMap = $event" />
-  <PlacedMapObjects v-if="tileMap" :key="mapStore.mapId" :tilemap="tileMap" />
-  <Characters v-if="tileMap && mapStore.characters" :tilemap="tileMap" />
+  <MapTiles :key="mapStore.mapId" :tileMap :tileMapLayer />
+  <PlacedMapObjects v-if="tileMap" :key="mapStore.mapId" :tileMap :tileMapLayer />
+  <Characters v-if="tileMap && mapStore.characters" :tileMap />
 </template>
 
 <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 { useGameStore } from '@/stores/gameStore'
 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 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) => {
@@ -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(() => {
   mapStore.reset()
   gameStore.connection?.off('map:character:teleport')
diff --git a/src/components/game/map/MapTiles.vue b/src/components/game/map/MapTiles.vue
index 54dcb96..a636b31 100644
--- a/src/components/game/map/MapTiles.vue
+++ b/src/components/game/map/MapTiles.vue
@@ -1,39 +1,38 @@
 <template>
-  <Controls v-if="tileLayer" :layer="tileLayer" :depth="0" />
+  <Controls v-if="tileMapLayer" :layer="tileMapLayer" :depth="0" />
 </template>
 
 <script setup lang="ts">
 import type { UUID } from '@/application/types'
 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 { useMapStore } from '@/stores/mapStore'
 import { useScene } from 'phavuer'
-import { onBeforeUnmount, shallowRef } from 'vue'
+import { onMounted } from 'vue'
 
-const emit = defineEmits(['tileMap:create'])
 const scene = useScene()
 const mapStore = useMapStore()
 const mapStorage = new MapStorage()
 
-const tileMap = shallowRef<Phaser.Tilemaps.Tilemap>()
-const tileLayer = shallowRef<Phaser.Tilemaps.TilemapLayer>()
+const props = defineProps<{
+  tileMap: Phaser.Tilemaps.Tilemap
+  tileMapLayer: Phaser.Tilemaps.TilemapLayer
+}>()
 
 loadTileTexturesFromMapTileArray(mapStore.mapId as UUID, scene)
   .then(() => mapStorage.get(mapStore.mapId))
   .then((mapData) => {
     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))
 
-onBeforeUnmount(() => {
-  if (!tileMap.value) return
-  tileMap.value.destroyLayer('tiles')
-  tileMap.value.removeAllLayers()
-  tileMap.value.destroy()
+onMounted(async () => {
+  if (!mapStore.mapId) return
+
+  const map = await mapStorage.get(mapStore.mapId)
+  if (!map) return
+
+  placeTiles(props.tileMap, props.tileMapLayer, map.tiles)
 })
 </script>
diff --git a/src/components/game/map/PlacedMapObjects.vue b/src/components/game/map/PlacedMapObjects.vue
index 2b9f2f4..516a3ad 100644
--- a/src/components/game/map/PlacedMapObjects.vue
+++ b/src/components/game/map/PlacedMapObjects.vue
@@ -1,5 +1,5 @@
 <template>
-  <PlacedMapObject v-for="placedMapObject in items" :tilemap="tilemap" :placedMapObject />
+  <PlacedMapObject v-for="placedMapObject in items" :tileMap :tileMapLayer :placedMapObject />
 </template>
 
 <script setup lang="ts">
@@ -8,9 +8,11 @@ import PlacedMapObject from '@/components/game/map/partials/PlacedMapObject.vue'
 import { MapStorage } from '@/storage/storages'
 import { useMapStore } from '@/stores/mapStore'
 import { onMounted, ref } from 'vue'
+import TilemapLayer = Phaser.Tilemaps.TilemapLayer
 
 defineProps<{
-  tilemap: Phaser.Tilemaps.Tilemap
+  tileMap: Phaser.Tilemaps.Tilemap
+  tileMapLayer: TilemapLayer
 }>()
 
 const mapStore = useMapStore()
diff --git a/src/components/gameMaster/mapEditor/Map.vue b/src/components/gameMaster/mapEditor/Map.vue
index 43b8b91..8c1b7e9 100644
--- a/src/components/gameMaster/mapEditor/Map.vue
+++ b/src/components/gameMaster/mapEditor/Map.vue
@@ -1,6 +1,6 @@
 <template>
-  <MapTiles ref="mapTiles" v-if="tileMap" :tileMapLayer :tileMap @tileMap:create="tileMap = $event" />
-  <PlacedMapObjects ref="mapObjects" v-if="tileMap" :tileMapLayer :tileMap />
+  <MapTiles ref="mapTiles" v-if="tileMap" :tileMap :tileMapLayer />
+  <PlacedMapObjects ref="mapObjects" v-if="tileMap" :tileMap :tileMapLayer />
   <MapEventTiles ref="eventTiles" v-if="tileMap" :tileMap />
 </template>
 
@@ -78,7 +78,6 @@ onMounted(() => {
   let mapValue = mapEditor.currentMap.value
   if (!mapValue) return
   tileMap.value = createTileMap(scene, mapValue)
-  mapTiles.value?.$emit('tileMap:create', tileMap.value)
   tileMapLayer.value = createTileLayer(tileMap.value, mapValue)
 
   addEventListener('keydown', handleKeyDown)
diff --git a/src/components/gameMaster/mapEditor/mapPartials/MapTiles.vue b/src/components/gameMaster/mapEditor/mapPartials/MapTiles.vue
index 541fa4f..755b3ef 100644
--- a/src/components/gameMaster/mapEditor/mapPartials/MapTiles.vue
+++ b/src/components/gameMaster/mapEditor/mapPartials/MapTiles.vue
@@ -1,15 +1,13 @@
 <template>
-  <Controls v-if="props.tileMapLayer" :layer="props.tileMapLayer" :depth="0" />
+  <Controls v-if="tileMapLayer" :layer="tileMapLayer" :depth="0" />
 </template>
 
 <script setup lang="ts">
 import Controls from '@/components/utilities/Controls.vue'
 import { useMapEditorComposable } from '@/composables/useMapEditorComposable'
-import { createTileArray, getTile, placeTile, setLayerTiles } from '@/services/mapService'
-import { useScene } from 'phavuer'
+import { createTileArray, getTile, placeTile, placeTiles } from '@/services/mapService'
 import { onMounted, ref, watch } from 'vue'
 
-const emit = defineEmits(['tileMap:create'])
 const mapEditor = useMapEditorComposable()
 
 defineExpose({ handlePointer, finalizeCommand, undo, redo })
@@ -80,7 +78,7 @@ function paint(pointer: Phaser.Input.Pointer) {
 
   // Set new tileArray with selected tile
   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
   map.tiles = tileArray
@@ -182,7 +180,7 @@ function updateMapTiles() {
   let indexedCommands = commandStack.slice(0, commandIndex.value)
   let modifiedTiles = applyCommands(originTiles, ...indexedCommands)
 
-  setLayerTiles(props.tileMap, props.tileMapLayer, modifiedTiles)
+  placeTiles(props.tileMap, props.tileMapLayer, modifiedTiles)
   mapEditor.currentMap.value.tiles = modifiedTiles
 }
 
@@ -196,7 +194,7 @@ watch(
   (shouldClear) => {
     if (shouldClear && mapEditor.currentMap.value) {
       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.resetClearTilesFlag()
     }
@@ -210,6 +208,6 @@ onMounted(async () => {
   //Clone
   originTiles = cloneArray(mapState.tiles)
 
-  setLayerTiles(props.tileMap, props.tileMapLayer, mapState.tiles)
+  placeTiles(props.tileMap, props.tileMapLayer, mapState.tiles)
 })
 </script>
diff --git a/src/components/gameMaster/mapEditor/mapPartials/PlacedMapObjects.vue b/src/components/gameMaster/mapEditor/mapPartials/PlacedMapObjects.vue
index ebf322c..ae2cac4 100644
--- a/src/components/gameMaster/mapEditor/mapPartials/PlacedMapObjects.vue
+++ b/src/components/gameMaster/mapEditor/mapPartials/PlacedMapObjects.vue
@@ -1,6 +1,6 @@
 <template>
   <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>
 
 <script setup lang="ts">
diff --git a/src/services/mapService.ts b/src/services/mapService.ts
index 74c1d3a..68a1b7f 100644
--- a/src/services/mapService.ts
+++ b/src/services/mapService.ts
@@ -53,8 +53,8 @@ export function placeTile(map: Tilemap, layer: TilemapLayer, positionX: number,
   layer.putTileAt(tileImg.firstgid, positionX, positionY)
 }
 
-export function setLayerTiles(map: Tilemap, layer: TilemapLayer, tiles: string[][]) {
-  if (!tiles) return
+export function placeTiles(map: Tilemap, layer: TilemapLayer, tiles: string[][]) {
+  if (!map || !layer || !tiles) return
 
   tiles.forEach((row: string[], y: number) => {
     row.forEach((tile: string, x: number) => {
@@ -113,6 +113,7 @@ export async function loadAllTileTextures(scene: Phaser.Scene) {
   const tiles = await tileStorage.getAll()
 
   await loadTileTextures(tiles, scene)
+  scene.load.start()
 }
 
 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)
 }
 
-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 tilesetImages = tilesArray.map((tile: string, index: number) => {