Improved movement logic

This commit is contained in:
Dennis Postma 2025-02-16 17:14:24 +01:00
parent 920baaebde
commit 15dc331a43
2 changed files with 83 additions and 44 deletions

View File

@ -7,7 +7,76 @@ 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)
}
@ -23,32 +92,21 @@ export function useGameControlsComposable(scene: Phaser.Scene, layer: Phaser.Til
const pointerTile = getTile(layer, pointer.worldX, pointer.worldY)
if (!pointerTile) return
gameStore.connection?.emit(SocketEvent.MAP_CHARACTER_MOVE, {
positionX: pointerTile.x,
positionY: pointerTile.y
})
emitMovement(pointerTile.x, pointerTile.y)
}
const pressedKeys = new Set<string>()
let moveInterval: number | null = null
// Keyboard Handlers
function handleKeyDown(event: KeyboardEvent) {
if (!gameStore.character) return
if (['ArrowLeft', 'ArrowRight', 'ArrowUp', 'ArrowDown'].includes(event.key)) {
// Prevent key repeat events
if (ARROW_KEYS.includes(event.key as (typeof ARROW_KEYS)[number])) {
if (event.repeat) return
pressedKeys.add(event.key)
// Start movement loop if not already running
if (!moveInterval) {
moveInterval = window.setInterval(moveCharacter, 50)
moveCharacter() // Move immediately on first press
}
updateCurrentPosition()
startMovementLoop()
}
// Attack on CTRL
if (event.key === 'Control') {
gameStore.connection?.emit(SocketEvent.MAP_CHARACTER_ATTACK)
}
@ -57,36 +115,14 @@ export function useGameControlsComposable(scene: Phaser.Scene, layer: Phaser.Til
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
let newX = positionX
let newY = positionY
// Calculate new position based on pressed keys
if (pressedKeys.has('ArrowLeft')) newX--
if (pressedKeys.has('ArrowRight')) newX++
if (pressedKeys.has('ArrowUp')) newY--
if (pressedKeys.has('ArrowDown')) newY++
// Only emit if position changed
if (newX !== positionX || newY !== positionY) {
gameStore.connection?.emit(SocketEvent.MAP_CHARACTER_MOVE, {
positionX: newX,
positionY: newY
})
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)
@ -96,6 +132,9 @@ export function useGameControlsComposable(scene: Phaser.Scene, layer: Phaser.Til
}
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)

View File

@ -62,8 +62,8 @@ export function createTileArray(width: number, height: number, tile: string = 'b
return Array.from({ length: height }, () => Array.from({ length: width }, () => tile))
}
export const calculateIsometricDepth = (positionX: number, positionY: number, pivotPoints: { x: number; y: number; }[] = []) => {
return Math.max(positionX + positionY);
export const calculateIsometricDepth = (positionX: number, positionY: number, pivotPoints: { x: number; y: number }[] = []) => {
return Math.max(positionX + positionY)
}
async function loadTileTextures(tiles: TileT[], scene: Phaser.Scene) {