From e714bd94b55af14bc2a05e7b79d41fc803616581 Mon Sep 17 00:00:00 2001
From: Dennis Postma <dennis@directonline.io>
Date: Sun, 21 Jul 2024 20:03:36 +0200
Subject: [PATCH] Refractor and improve controls component

---
 src/components/utilities/Controls.vue | 123 ++++++++++++++------------
 1 file changed, 66 insertions(+), 57 deletions(-)

diff --git a/src/components/utilities/Controls.vue b/src/components/utilities/Controls.vue
index c4c4712..44fdb47 100644
--- a/src/components/utilities/Controls.vue
+++ b/src/components/utilities/Controls.vue
@@ -1,91 +1,100 @@
 <template>
-  <Image :depth="2" texture="waypoint" :x="waypoint.x" :y="waypoint.y" :visible="waypoint.visible" />
+  <Image
+    :depth="2"
+    texture="waypoint"
+    :x="waypoint.x"
+    :y="waypoint.y"
+    :visible="waypoint.visible"
+  />
 </template>
 
 <script setup lang="ts">
 import { Image, useScene } from 'phavuer'
 import { onBeforeUnmount, ref, watch } from 'vue'
+import { storeToRefs } from 'pinia'
 import config from '@/config'
 import { getTile, tileToWorldXY } from '@/services/zone'
-import { useZoneStore } from '@/stores/zone'
 import { useZoneEditorStore } from '@/stores/zoneEditor'
 
-const zoneStore = useZoneStore()
-const zoneEditorStore = useZoneEditorStore()
-const scene = useScene()
-const props = defineProps({
+const props = defineProps<{
   layer: Phaser.Tilemaps.TilemapLayer
-})
+}>()
+
+const scene = useScene()
+const zoneEditorStore = useZoneEditorStore()
+const { tool } = storeToRefs(zoneEditorStore)
+
 const waypoint = ref({
   visible: false,
   x: 0,
   y: 0
 })
 
-function onPointerMove(pointer: Phaser.Input.Pointer) {
-  const px = scene.cameras.main.worldView.x + pointer.x
-  const py = scene.cameras.main.worldView.y + pointer.y
+const cam = ref(scene.cameras.main)
 
-  const pointer_tile = getTile(px, py, props.layer) as Phaser.Tilemaps.Tile
-  if (!pointer_tile) {
+function updateWaypoint(pointer: Phaser.Input.Pointer) {
+  const { x: px, y: py } = scene.cameras.main.getWorldPoint(pointer.x, pointer.y)
+  const pointerTile = getTile(px, py, props.layer) as Phaser.Tilemaps.Tile
+
+  if (!pointerTile) {
     waypoint.value.visible = false
     return
   }
 
-  waypoint.value.visible = true
-
-  // Convert tile coordinates to world coordinates
-  const worldPoint = tileToWorldXY(props.layer, pointer_tile.x, pointer_tile.y)
-  waypoint.value.x = worldPoint.position_x
-  waypoint.value.y = worldPoint.position_y + config.tile_size.y + 15
+  const worldPoint = tileToWorldXY(props.layer, pointerTile.x, pointerTile.y)
+  waypoint.value = {
+    visible: true,
+    x: worldPoint.position_x,
+    y: worldPoint.position_y + config.tile_size.y + 15
+  }
 }
 
-scene.input.on(Phaser.Input.Events.POINTER_MOVE, onPointerMove)
-
-// Zone camera system
 function dragZone(pointer: Phaser.Input.Pointer) {
   if (!pointer.isDown) return
-  cam.scrollX -= (pointer.x - pointer.prevPosition.x) / cam.zoom
-  cam.scrollY -= (pointer.y - pointer.prevPosition.y) / cam.zoom
+  const { x, y, prevPosition } = pointer
+  cam.value.scrollX -= (x - prevPosition.x) / cam.value.zoom
+  cam.value.scrollY -= (y - prevPosition.y) / cam.value.zoom
 }
-let cam = scene.cameras.main
-scene.input.on(Phaser.Input.Events.POINTER_MOVE, dragZone)
 
-watch(
-  () => zoneEditorStore.tool,
-  () => {
-    // @TODO : change to zone for when loading other maps
-    if (zoneEditorStore.tool === 'move') {
-      scene.input.on(Phaser.Input.Events.POINTER_MOVE, dragZone)
-    } else {
-      scene.input.off(Phaser.Input.Events.POINTER_MOVE, dragZone)
-    }
-  },
-  { deep: true }
-)
-
-// if ctrl is pressed and mouse is down , then drag the zone
-scene.input.on(Phaser.Input.Events.POINTER_DOWN, (pointer: Phaser.Input.Pointer) => {
+function handleZoom(pointer: Phaser.Input.Pointer, _: any, __: any, deltaY: number) {
   if (pointer.event.altKey) {
+    scene.scale.setZoom(scene.scale.zoom - deltaY * 0.01)
+    cam.value = scene.cameras.main
+  }
+}
+
+function setupEventListeners() {
+  scene.input.on(Phaser.Input.Events.POINTER_MOVE, updateWaypoint)
+  scene.input.on(Phaser.Input.Events.POINTER_WHEEL, handleZoom)
+
+  scene.input.on(Phaser.Input.Events.POINTER_DOWN, (pointer: Phaser.Input.Pointer) => {
+    if (pointer.event.altKey || tool.value === 'move') {
+      scene.input.on(Phaser.Input.Events.POINTER_MOVE, dragZone)
+    }
+  })
+
+  scene.input.on(Phaser.Input.Events.POINTER_UP, () => {
+    scene.input.off(Phaser.Input.Events.POINTER_MOVE, dragZone)
+  })
+}
+
+function cleanupEventListeners() {
+  scene.input.off(Phaser.Input.Events.POINTER_MOVE, updateWaypoint)
+  scene.input.off(Phaser.Input.Events.POINTER_MOVE, dragZone)
+  scene.input.off(Phaser.Input.Events.POINTER_DOWN)
+  scene.input.off(Phaser.Input.Events.POINTER_UP)
+  scene.input.off(Phaser.Input.Events.POINTER_WHEEL, handleZoom)
+}
+
+setupEventListeners()
+
+watch(tool, (newTool) => {
+  if (newTool === 'move') {
     scene.input.on(Phaser.Input.Events.POINTER_MOVE, dragZone)
-  } else if (zoneEditorStore.tool !== 'move') {
+  } else {
     scene.input.off(Phaser.Input.Events.POINTER_MOVE, dragZone)
   }
 })
 
-/**
- * Zoom in and out
- */
-scene.input.on(Phaser.Input.Events.POINTER_WHEEL, (pointer: Phaser.Input.Pointer, gameObjects: Phaser.GameObjects.GameObject[], deltaX: number, deltaY: number) => {
-  if (pointer.event.altKey) {
-    scene.scale.setZoom(scene.scale.zoom - deltaY * 0.01)
-    cam = scene.cameras.main
-  }
-})
-
-// Unload funcs
-onBeforeUnmount(() => {
-  scene.input.off(Phaser.Input.Events.POINTER_MOVE, onPointerMove)
-  scene.input.off(Phaser.Input.Events.POINTER_MOVE, dragZone)
-})
-</script>
+onBeforeUnmount(cleanupEventListeners)
+</script>
\ No newline at end of file