1
0
forked from noxious/client

177 lines
5.6 KiB
Vue

<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>