148 lines
4.2 KiB
TypeScript
148 lines
4.2 KiB
TypeScript
import { SocketEvent } from '@/application/enums'
|
|
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)
|
|
const pressedKeys = new Set<string>()
|
|
|
|
let moveTimeout: NodeJS.Timeout | null = null
|
|
let currentPosition = {
|
|
x: 0,
|
|
y: 0
|
|
}
|
|
|
|
// Movement constants
|
|
const MOVEMENT_DELAY = 110 // Milliseconds between moves
|
|
const ARROW_KEYS = ['ArrowLeft', 'ArrowRight', 'ArrowUp', 'ArrowDown'] as const
|
|
|
|
function updateCurrentPosition() {
|
|
if (!gameStore.character) return
|
|
currentPosition = {
|
|
x: gameStore.character.positionX,
|
|
y: gameStore.character.positionY
|
|
}
|
|
}
|
|
|
|
function calculateNewPosition() {
|
|
let newX = currentPosition.x
|
|
let newY = currentPosition.y
|
|
|
|
if (pressedKeys.has('ArrowLeft')) newX--
|
|
if (pressedKeys.has('ArrowRight')) newX++
|
|
if (pressedKeys.has('ArrowUp')) newY--
|
|
if (pressedKeys.has('ArrowDown')) newY++
|
|
|
|
return { newX, newY }
|
|
}
|
|
|
|
function emitMovement(x: number, y: number) {
|
|
if (x === currentPosition.x && y === currentPosition.y) return
|
|
|
|
gameStore.connection?.emit(SocketEvent.MAP_CHARACTER_MOVE, {
|
|
positionX: x,
|
|
positionY: y
|
|
})
|
|
|
|
currentPosition = { x, y }
|
|
}
|
|
|
|
function startMovementLoop() {
|
|
if (moveTimeout) return
|
|
|
|
const move = () => {
|
|
if (pressedKeys.size === 0) {
|
|
stopMovementLoop()
|
|
return
|
|
}
|
|
|
|
updateCurrentPosition()
|
|
const { newX, newY } = calculateNewPosition()
|
|
emitMovement(newX, newY)
|
|
|
|
moveTimeout = setTimeout(move, MOVEMENT_DELAY)
|
|
}
|
|
|
|
move()
|
|
}
|
|
|
|
function stopMovementLoop() {
|
|
if (moveTimeout) {
|
|
clearTimeout(moveTimeout)
|
|
moveTimeout = null
|
|
}
|
|
}
|
|
|
|
// Pointer Handlers
|
|
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
|
|
|
|
emitMovement(pointerTile.x, pointerTile.y)
|
|
}
|
|
|
|
// Keyboard Handlers
|
|
function handleKeyDown(event: KeyboardEvent) {
|
|
if (!gameStore.character) return
|
|
|
|
if (ARROW_KEYS.includes(event.key as (typeof ARROW_KEYS)[number])) {
|
|
if (event.repeat) return
|
|
|
|
pressedKeys.add(event.key)
|
|
updateCurrentPosition()
|
|
startMovementLoop()
|
|
}
|
|
|
|
if (event.key === 'Control') {
|
|
gameStore.connection?.emit(SocketEvent.MAP_CHARACTER_ATTACK)
|
|
}
|
|
}
|
|
|
|
function handleKeyUp(event: KeyboardEvent) {
|
|
pressedKeys.delete(event.key)
|
|
|
|
if (pressedKeys.size === 0) {
|
|
stopMovementLoop()
|
|
}
|
|
}
|
|
|
|
const setupControls = () => {
|
|
updateCurrentPosition() // Initialize position
|
|
|
|
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 = () => {
|
|
stopMovementLoop()
|
|
pressedKeys.clear()
|
|
|
|
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 }
|
|
}
|