import { getTile } from '@/services/mapService' import { useGameStore } from '@/stores/gameStore' import type { Ref } from 'vue' import { useBaseControlsComposable } from './useBaseControlsComposable' export function useGameControlsComposable(scene: Phaser.Scene, layer: Phaser.Tilemaps.TilemapLayer, waypoint: Ref<{ visible: boolean; x: number; y: number }>, camera: Phaser.Cameras.Scene2D.Camera) { const gameStore = useGameStore() const baseHandlers = useBaseControlsComposable(scene, layer, waypoint, camera) function handlePointerDown(pointer: Phaser.Input.Pointer) { baseHandlers.startDragging(pointer) } function handlePointerMove(pointer: Phaser.Input.Pointer) { baseHandlers.updateWaypoint(pointer.worldX, pointer.worldY) baseHandlers.handleDragMap(pointer) } function handlePointerUp(pointer: Phaser.Input.Pointer) { baseHandlers.stopDragging() const pointerTile = getTile(layer, pointer.worldX, pointer.worldY) if (!pointerTile) return gameStore.connection?.emit('map:character:move', { positionX: pointerTile.x, positionY: pointerTile.y }) } const pressedKeys = new Set() let moveInterval: number | null = null function handleKeyDown(event: KeyboardEvent) { if (!gameStore.character) return if (['ArrowLeft', 'ArrowRight', 'ArrowUp', 'ArrowDown'].includes(event.key)) { // Prevent key repeat events if (event.repeat) return pressedKeys.add(event.key) // Start movement loop if not already running if (!moveInterval) { moveInterval = window.setInterval(moveCharacter, 75) // Increased interval to match server throttle `MOVEMENT_THROTTLE` moveCharacter() // Move immediately on first press } } // Attack on CTRL if (event.key === 'Control') { gameStore.connection?.emit('map:character:attack') } } function handleKeyUp(event: KeyboardEvent) { pressedKeys.delete(event.key) // If no movement keys are pressed, clear the interval if (pressedKeys.size === 0 && moveInterval) { clearInterval(moveInterval) moveInterval = null } } function moveCharacter() { if (!gameStore.character) return const { positionX, positionY } = gameStore.character if (pressedKeys.has('ArrowLeft')) { gameStore.connection?.emit('map:character:move', { positionX: positionX - 1, positionY: positionY }) } if (pressedKeys.has('ArrowRight')) { gameStore.connection?.emit('map:character:move', { positionX: positionX + 1, positionY: positionY }) } if (pressedKeys.has('ArrowUp')) { gameStore.connection?.emit('map:character:move', { positionX: positionX, positionY: positionY - 1 }) } if (pressedKeys.has('ArrowDown')) { gameStore.connection?.emit('map:character:move', { positionX: positionX, positionY: positionY + 1 }) } } const setupControls = () => { scene.input.on(Phaser.Input.Events.POINTER_DOWN, handlePointerDown) scene.input.on(Phaser.Input.Events.POINTER_MOVE, handlePointerMove) scene.input.on(Phaser.Input.Events.POINTER_UP, handlePointerUp) scene.input.on(Phaser.Input.Events.POINTER_WHEEL, baseHandlers.handleZoom) scene.input.keyboard!.on('keydown', handleKeyDown) scene.input.keyboard!.on('keyup', handleKeyUp) } const cleanupControls = () => { scene.input.off(Phaser.Input.Events.POINTER_DOWN, handlePointerDown) scene.input.off(Phaser.Input.Events.POINTER_MOVE, handlePointerMove) scene.input.off(Phaser.Input.Events.POINTER_UP, handlePointerUp) scene.input.off(Phaser.Input.Events.POINTER_WHEEL, baseHandlers.handleZoom) scene.input.keyboard!.off('keydown', handleKeyDown) scene.input.keyboard!.off('keyup', handleKeyUp) } return { setupControls, cleanupControls } }