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) => {