Map editor improvements

This commit is contained in:
Dennis Postma 2025-01-05 00:07:55 +01:00
parent ae0841889b
commit ef807982a5
10 changed files with 57 additions and 57 deletions

View File

@ -15,7 +15,7 @@ export type HttpResponse<T> = {
export type AssetDataT = {
key: string
data: string
group: 'tiles' | 'objects' | 'sprites' | 'sprite_animations' | 'sound' | 'music' | 'ui' | 'font' | 'other'
group: 'tiles' | 'map_objects' | 'sprites' | 'sprite_animations' | 'sound' | 'music' | 'ui' | 'font' | 'other'
updatedAt: Date
originX?: number
originY?: number

View File

@ -1,5 +1,5 @@
<template>
<MapObject v-for="mapObject in mapStore.map?.mapObjects" :tilemap="tilemap" :mapObject />
<MapObject v-for="mapObject in mapStore.map?.mapObjects" :tilemap="tilemap" :placedMapObject />
</template>
<script setup lang="ts">

View File

@ -1,5 +1,5 @@
<template>
<Image v-if="gameStore.getLoadedAsset(props.mapObject.object.id)" v-bind="imageProps" />
<Image v-if="gameStore.getLoadedAsset(props.placedMapObject.mapObject.id)" v-bind="imageProps" />
</template>
<script setup lang="ts">
@ -12,29 +12,29 @@ import { computed } from 'vue'
const props = defineProps<{
tilemap: Phaser.Tilemaps.Tilemap
mapObject: PlacedMapObject
placedMapObject: PlacedMapObject
}>()
const gameStore = useGameStore()
const scene = useScene()
const imageProps = computed(() => ({
depth: calculateIsometricDepth(props.mapObject.positionX, props.mapObject.positionY, props.mapObject.object.frameWidth, props.mapObject.object.frameHeight),
x: tileToWorldX(props.tilemap, props.mapObject.positionX, props.mapObject.positionY),
y: tileToWorldY(props.tilemap, props.mapObject.positionX, props.mapObject.positionY),
flipX: props.mapObject.isRotated,
texture: props.mapObject.object.id,
originY: Number(props.mapObject.object.originX),
originX: Number(props.mapObject.object.originY)
depth: calculateIsometricDepth(props.placedMapObject.positionX, props.placedMapObject.positionY, props.placedMapObject.mapObject.frameWidth, props.placedMapObject.mapObject.frameHeight),
x: tileToWorldX(props.tilemap, props.placedMapObject.positionX, props.placedMapObject.positionY),
y: tileToWorldY(props.tilemap, props.placedMapObject.positionX, props.placedMapObject.positionY),
flipX: props.placedMapObject.isRotated,
texture: props.placedMapObject.mapObject.id,
originY: Number(props.placedMapObject.mapObject.originX),
originX: Number(props.placedMapObject.mapObject.originY)
}))
loadTexture(scene, {
key: props.mapObject.object.id,
data: '/assets/objects/' + props.mapObject.object.id + '.png',
group: 'objects',
updatedAt: props.mapObject.object.updatedAt,
frameWidth: props.mapObject.object.frameWidth,
frameHeight: props.mapObject.object.frameHeight
key: props.placedMapObject.mapObject.id,
data: '/assets/map_objects/' + props.placedMapObject.mapObject.id + '.png',
group: 'map_objects',
updatedAt: props.placedMapObject.mapObject.updatedAt,
frameWidth: props.placedMapObject.mapObject.frameWidth,
frameHeight: props.placedMapObject.mapObject.frameHeight
} as AssetDataT).catch((error) => {
console.error('Error loading texture:', error)
})

View File

@ -98,11 +98,11 @@ function removeObject() {
})
}
function refreshObjectList(unsetSelectedObject = true) {
function refreshObjectList(unsetSelectedMapObject = true) {
gameStore.connection?.emit('gm:mapObject:list', {}, (response: MapObject[]) => {
assetManagerStore.setMapObjectList(response)
if (unsetSelectedObject) {
if (unsetSelectedMapObject) {
assetManagerStore.setSelectedMapObject(null)
}

View File

@ -20,7 +20,7 @@ import MapObjects from '@/components/gameMaster/mapEditor/mapPartials/MapObjects
import MapTiles from '@/components/gameMaster/mapEditor/mapPartials/MapTiles.vue'
import MapList from '@/components/gameMaster/mapEditor/partials/MapList.vue'
import MapSettings from '@/components/gameMaster/mapEditor/partials/MapSettings.vue'
import ObjectList from '@/components/gameMaster/mapEditor/partials/ObjectList.vue'
import ObjectList from '@/components/gameMaster/mapEditor/partials/MapObjectList.vue'
import TeleportModal from '@/components/gameMaster/mapEditor/partials/TeleportModal.vue'
import TileList from '@/components/gameMaster/mapEditor/partials/TileList.vue'
// Components

View File

@ -1,6 +1,6 @@
<template>
<SelectedMapObject v-if="selectedMapObject" :mapObject="selectedMapObject" :movingMapObject="movingMapObject" @move="moveMapObject" @rotate="rotateMapObject" @delete="deleteMapObject" />
<MapObject v-for="mapObject in mapEditorStore.map?.mapObjects" :tilemap="tilemap" :mapObject :selectedMapObject :movingMapObject @pointerup="clickMapObject(mapObject)" />
<MapObject v-for="mapObject in mapEditorStore.map?.placedMapObjects" :tilemap="tilemap" :mapObject :selectedMapObject :movingMapObject @pointerup="clickMapObject(mapObject)" />
</template>
<script setup lang="ts">
@ -33,7 +33,7 @@ function pencil(pointer: Phaser.Input.Pointer) {
if (mapEditorStore.drawMode !== 'object') return
// Check if there is a selected object
if (!mapEditorStore.selectedObject) return
if (!mapEditorStore.selectedMapObject) return
// Check if left mouse button is pressed
if (!pointer.isDown) return
@ -56,8 +56,8 @@ function pencil(pointer: Phaser.Input.Pointer) {
id: uuidv4(),
mapId: mapEditorStore.map.id,
map: mapEditorStore.map,
objectId: mapEditorStore.selectedObject.id,
object: mapEditorStore.selectedObject,
objectId: mapEditorStore.selectedMapObject.id,
object: mapEditorStore.selectedMapObject,
depth: 0,
isRotated: false,
positionX: tile.x,
@ -123,11 +123,11 @@ function objectPicker(pointer: Phaser.Input.Pointer) {
if (!tile) return
// Check if object already exists on position
const existingObject = mapEditorStore.map.placedMapObjects.find((object) => object.positionX === tile.x && object.positionY === tile.y)
if (!existingObject) return
const existingMapObject = mapEditorStore.map.placedMapObjects.find((object) => object.positionX === tile.x && object.positionY === tile.y)
if (!existingMapObject) return
// Select the object
mapEditorStore.setSelectedObject(existingObject)
mapEditorStore.setSelectedMapObject(existingMapObject)
}
function moveMapObject(id: string) {
@ -184,7 +184,7 @@ function clickMapObject(mapObject: MapObjectT) {
// If alt is pressed, select the object
if (scene.input.activePointer.event.altKey) {
mapEditorStore.setSelectedObject(mapObject.object)
mapEditorStore.setSelectedMapObject(mapObject.mapObject)
}
}
@ -204,20 +204,20 @@ onUnmounted(() => {
scene.input.off(Phaser.Input.Events.POINTER_DOWN, objectPicker)
})
// watch mapEditorStore.objectList and update originX and originY of objects in mapObjects
// watch mapEditorStore.mapObjectList and update originX and originY of objects in mapObjects
watch(
() => mapEditorStore.objectList,
() => mapEditorStore.mapObjectList,
(newObjects) => {
if (!mapEditorStore.map) return
console.log(mapEditorStore.map.placedMapObjects)
const updatedMapObjects = mapEditorStore.map.placedMapObjects.map((mapObject) => {
const updatedObject = newObjects.find((obj) => obj.id === mapObject.object.id)
const updatedObject = newObjects.find((obj) => obj.id === mapObject.mapObject.id)
if (updatedObject) {
return {
...mapObject,
object: {
...mapObject.object,
...mapObject.mapObject,
originX: updatedObject.originX,
originY: updatedObject.originY
}
@ -232,12 +232,12 @@ watch(
mapObjects: updatedMapObjects
})
// Update selectedObject if it's set
if (mapEditorStore.selectedObject) {
const updatedObject = newObjects.find((obj) => obj.id === mapEditorStore.selectedObject?.id)
// Update selectedMapObject if it's set
if (mapEditorStore.selectedMapObject) {
const updatedObject = newObjects.find((obj) => obj.id === mapEditorStore.selectedMapObject?.id)
if (updatedObject) {
mapEditorStore.setSelectedObject({
...mapEditorStore.selectedObject,
mapEditorStore.setSelectedMapObject({
...mapEditorStore.selectedMapObject,
originX: updatedObject.originX,
originY: updatedObject.originY
})

View File

@ -26,7 +26,7 @@
</template>
<script setup lang="ts">
import type { Map } from '@/application/types'
import type { Map, UUID } from '@/application/types'
import CreateMap from '@/components/gameMaster/mapEditor/partials/CreateMap.vue'
import Modal from '@/components/utilities/Modal.vue'
import { useGameStore } from '@/stores/gameStore'
@ -46,14 +46,14 @@ function fetchMaps() {
})
}
function loadMap(id: number) {
function loadMap(id: UUID) {
gameStore.connection?.emit('gm:map:request', { mapId: id }, (response: Map) => {
mapEditorStore.setMap(response)
})
mapEditorStore.toggleMapListModal()
}
function deleteMap(id: number) {
function deleteMap(id: UUID) {
gameStore.connection?.emit('gm:map:delete', { mapId: id }, () => {
fetchMaps()
})

View File

@ -1,5 +1,5 @@
<template>
<Modal :isModalOpen="mapEditorStore.isObjectListModalShown" :modal-width="645" :modal-height="260" @modal:close="() => (mapEditorStore.isObjectListModalShown = false)" :bg-style="'none'">
<Modal :isModalOpen="mapEditorStore.isMapObjectListModalShown" :modal-width="645" :modal-height="260" @modal:close="() => (mapEditorStore.isMapObjectListModalShown = false)" :bg-style="'none'">
<template #modalHeader>
<h3 class="text-lg text-white">Objects</h3>
</template>
@ -20,16 +20,16 @@
</div>
<div class="h-full overflow-auto">
<div class="flex justify-between flex-wrap gap-2.5 items-center">
<div v-for="(object, index) in filteredObjects" :key="index" class="max-w-1/4 inline-block">
<div v-for="(mapObject, index) in filteredMapObjects" :key="index" class="max-w-1/4 inline-block">
<img
class="border-2 border-solid max-w-full"
:src="`${config.server_endpoint}/assets/objects/${object.id}.png`"
:src="`${config.server_endpoint}/assets/objects/${mapObject.id}.png`"
alt="Object"
@click="mapEditorStore.setSelectedObject(object)"
@click="mapEditorStore.setSelectedMapObject(mapObject)"
:class="{
'cursor-pointer transition-all duration-300': true,
'border-cyan shadow-lg scale-105': mapEditorStore.selectedObject?.id === object.id,
'border-transparent hover:border-gray-300': mapEditorStore.selectedObject?.id !== object.id
'border-cyan shadow-lg scale-105': mapEditorStore.selectedMapObject?.id === mapObject.id,
'border-transparent hover:border-gray-300': mapEditorStore.selectedMapObject?.id !== mapObject.id
}"
/>
</div>
@ -42,7 +42,7 @@
<script setup lang="ts">
import config from '@/application/config'
import type { MapObject, PlacedMapObject } from '@/application/types'
import type { MapObject } from '@/application/types'
import Modal from '@/components/utilities/Modal.vue'
import { useGameStore } from '@/stores/gameStore'
import { useMapEditorStore } from '@/stores/mapEditorStore'
@ -55,12 +55,12 @@ const searchQuery = ref('')
const selectedTags = ref<string[]>([])
const uniqueTags = computed(() => {
const allTags = mapEditorStore.objectList.flatMap((obj) => obj.tags || [])
const allTags = mapEditorStore.mapObjectList.flatMap((obj) => obj.tags || [])
return Array.from(new Set(allTags))
})
const filteredObjects = computed(() => {
return mapEditorStore.objectList.filter((object) => {
const filteredMapObjects = computed(() => {
return mapEditorStore.mapObjectList.filter((object) => {
const matchesSearch = !searchQuery.value || object.name.toLowerCase().includes(searchQuery.value.toLowerCase())
const matchesTags = selectedTags.value.length === 0 || (object.tags && selectedTags.value.some((tag) => object.tags.includes(tag)))
return matchesSearch && matchesTags
@ -77,7 +77,7 @@ const toggleTag = (tag: string) => {
onMounted(async () => {
isModalOpen.value = true
gameStore.connection?.emit('gm:mapObject:list', {}, (response: MapObject[]) => {
gameStore.connection?.emit('', {}, (response: MapObject[]) => {
mapEditorStore.setMapObjectList(response)
})
})

View File

@ -33,7 +33,7 @@ export const useAssetManagerStore = defineStore('assetManager', () => {
mapObjectList.value = objects
}
function setSelectedObject(object: MapObject | null) {
function setSelectedMapObject(object: MapObject | null) {
selectedMapObject.value = object
}
@ -86,7 +86,7 @@ export const useAssetManagerStore = defineStore('assetManager', () => {
setSelectedTile,
setMapObjectList,
setCharacterTypeList,
setSelectedMapObject: setSelectedObject,
setSelectedMapObject: setSelectedMapObject,
setSpriteList,
setSelectedSprite,
setSelectedCharacterType,

View File

@ -21,7 +21,7 @@ export const useMapEditorStore = defineStore('mapEditor', {
tileList: [] as Tile[],
mapObjectList: [] as MapObject[],
selectedTile: '',
selectedObject: null as MapObject | null,
selectedMapObject: null as MapObject | null,
isTileListModalShown: false,
isMapObjectListModalShown: false,
isMapListModalShown: false,
@ -91,8 +91,8 @@ export const useMapEditorStore = defineStore('mapEditor', {
setSelectedTile(tile: string) {
this.selectedTile = tile
},
setSelectedObject(object: MapObject) {
this.selectedObject = object
setSelectedMapObject(object: MapObject) {
this.selectedMapObject = object
},
toggleSettingsModal() {
this.isSettingsModalShown = !this.isSettingsModalShown
@ -122,7 +122,7 @@ export const useMapEditorStore = defineStore('mapEditor', {
this.tool = 'move'
this.drawMode = 'tile'
this.selectedTile = ''
this.selectedObject = null
this.selectedMapObject = null
this.isTileListModalShown = false
this.isMapObjectListModalShown = false
this.isSettingsModalShown = false