<template> <SelectedZoneObject v-if="selectedZoneObject" :zoneObject="selectedZoneObject" @move="moveZoneObject" @rotate="rotateZoneObject" @delete="deleteZoneObject" /> <Image v-for="object in zoneEditorStore.zone?.zoneObjects" v-bind="getObjectImageProps(object)" @pointerup="() => selectedZoneObject = object" /> </template> <script setup lang="ts"> import { uuidv4 } from '@/utilities' import { calculateIsometricDepth, getTile, tileToWorldX, tileToWorldY } from '@/composables/zoneComposable' import { Image, useScene } from 'phavuer' import { useZoneEditorStore } from '@/stores/zoneEditorStore' import type { ZoneObject } from '@/types' import SelectedZoneObject from '@/components/gameMaster/zoneEditor/partials/SelectedZoneObject.vue' import { onBeforeMount, onBeforeUnmount, ref, watch } from 'vue' const scene = useScene() const zoneEditorStore = useZoneEditorStore() const selectedZoneObject = ref<ZoneObject | null>(null) const movingZoneObject = ref<ZoneObject | null>(null) const props = defineProps<{ tilemap: Phaser.Tilemaps.Tilemap }>() function getObjectImageProps(object: ZoneObject) { return { alpha: object.id === movingZoneObject.value?.id ? .5 : 1, depth: calculateIsometricDepth(object.positionX, object.positionY, object.object.frameWidth, object.object.frameHeight), tint: selectedZoneObject.value?.id === object.id ? 0x00ff00 : 0xffffff, x: tileToWorldX(props.tilemap, object.positionX, object.positionY), y: tileToWorldY(props.tilemap, object.positionX, object.positionY), flipX: object.isRotated, texture: object.object.id, originY: Number(object.object.originX), originX: Number(object.object.originY) } } function addZoneObject(pointer: Phaser.Input.Pointer) { if (!zoneEditorStore.zone) return // Check if tool is pencil if (zoneEditorStore.tool !== 'pencil') return // Check if draw mode is object if (zoneEditorStore.drawMode !== 'object') return // Check if there is a selected object if (!zoneEditorStore.selectedObject) return // Check if left mouse button is pressed if (!pointer.isDown) return // Check if there is a tile const tile = getTile(props.tilemap, pointer.worldX, pointer.worldY) if (!tile) return // Check if object already exists on position const existingObject = zoneEditorStore.zone?.zoneObjects.find((object) => object.positionX === tile.x && object.positionY === tile.y) if (existingObject) return const newObject = { id: uuidv4(), zoneId: zoneEditorStore.zone.id, zone: zoneEditorStore.zone, object: zoneEditorStore.selectedObject, depth: 0, isRotated: false, positionX: tile.x, positionY: tile.y } // Add new object to zoneObjects zoneEditorStore.zone.zoneObjects = zoneEditorStore.zone.zoneObjects.concat(newObject as ZoneObject) } function moveZoneObject(id: string) { if (!zoneEditorStore.zone) return movingZoneObject.value = zoneEditorStore.zone.zoneObjects.find((object) => object.id === id) as ZoneObject function handlePointerMove(pointer: Phaser.Input.Pointer) { if (!movingZoneObject.value) return const tile = getTile(props.tilemap, pointer.worldX, pointer.worldY) if (!tile) return movingZoneObject.value.positionX = tile.x movingZoneObject.value.positionY = tile.y } scene.input.on(Phaser.Input.Events.POINTER_MOVE, handlePointerMove) function handlePointerUp() { scene.input.off(Phaser.Input.Events.POINTER_MOVE, handlePointerMove) movingZoneObject.value = null } scene.input.on(Phaser.Input.Events.POINTER_UP, handlePointerUp) } function rotateZoneObject(id: string) { if (!zoneEditorStore.zone) return zoneEditorStore.zone.zoneObjects = zoneEditorStore.zone.zoneObjects.map((object) => { if (object.id === id) { return { ...object, isRotated: !object.isRotated } } return object }) } function deleteZoneObject(id: string) { if (!zoneEditorStore.zone) return zoneEditorStore.zone.zoneObjects = zoneEditorStore.zone.zoneObjects.filter((object) => object.id !== id) selectedZoneObject.value = null } onBeforeMount(() => { scene.input.on(Phaser.Input.Events.POINTER_DOWN, addZoneObject) scene.input.on(Phaser.Input.Events.POINTER_MOVE, addZoneObject) }) onBeforeUnmount(() => { scene.input.off(Phaser.Input.Events.POINTER_DOWN, addZoneObject) scene.input.off(Phaser.Input.Events.POINTER_MOVE, addZoneObject) }) // watch zoneEditorStore.objectList and update originX and originY of objects in zoneObjects watch( () => zoneEditorStore.objectList, (newObjects) => { if (!zoneEditorStore.zone) return console.log('Updating zone objects') const updatedZoneObjects = zoneEditorStore.zone.zoneObjects.map((zoneObject) => { const updatedObject = newObjects.find((obj) => obj.id === zoneObject.object.id) if (updatedObject) { return { ...zoneObject, object: { ...zoneObject.object, originX: updatedObject.originX, originY: updatedObject.originY } } } return zoneObject }) // Update the zone with the new zoneObjects zoneEditorStore.setZone({ ...zoneEditorStore.zone, zoneObjects: updatedZoneObjects }) // Update selectedObject if it's set if (zoneEditorStore.selectedObject) { const updatedObject = newObjects.find((obj) => obj.id === zoneEditorStore.selectedObject?.id) if (updatedObject) { zoneEditorStore.setSelectedObject({ ...zoneEditorStore.selectedObject, originX: updatedObject.originX, originY: updatedObject.originY }) } } }, { deep: true } ) </script>