forked from noxious/client
Improved movement logic
This commit is contained in:
parent
920baaebde
commit
15dc331a43
@ -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)
|
||||
|
@ -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) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user