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) {
|
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 gameStore = useGameStore()
|
||||||
const baseHandlers = useBaseControlsComposable(scene, layer, waypoint, camera)
|
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) {
|
function handlePointerDown(pointer: Phaser.Input.Pointer) {
|
||||||
baseHandlers.startDragging(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)
|
const pointerTile = getTile(layer, pointer.worldX, pointer.worldY)
|
||||||
if (!pointerTile) return
|
if (!pointerTile) return
|
||||||
|
|
||||||
gameStore.connection?.emit(SocketEvent.MAP_CHARACTER_MOVE, {
|
emitMovement(pointerTile.x, pointerTile.y)
|
||||||
positionX: pointerTile.x,
|
|
||||||
positionY: pointerTile.y
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const pressedKeys = new Set<string>()
|
// Keyboard Handlers
|
||||||
let moveInterval: number | null = null
|
|
||||||
|
|
||||||
function handleKeyDown(event: KeyboardEvent) {
|
function handleKeyDown(event: KeyboardEvent) {
|
||||||
if (!gameStore.character) return
|
if (!gameStore.character) return
|
||||||
|
|
||||||
if (['ArrowLeft', 'ArrowRight', 'ArrowUp', 'ArrowDown'].includes(event.key)) {
|
if (ARROW_KEYS.includes(event.key as (typeof ARROW_KEYS)[number])) {
|
||||||
// Prevent key repeat events
|
|
||||||
if (event.repeat) return
|
if (event.repeat) return
|
||||||
|
|
||||||
pressedKeys.add(event.key)
|
pressedKeys.add(event.key)
|
||||||
|
updateCurrentPosition()
|
||||||
// Start movement loop if not already running
|
startMovementLoop()
|
||||||
if (!moveInterval) {
|
|
||||||
moveInterval = window.setInterval(moveCharacter, 50)
|
|
||||||
moveCharacter() // Move immediately on first press
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Attack on CTRL
|
|
||||||
if (event.key === 'Control') {
|
if (event.key === 'Control') {
|
||||||
gameStore.connection?.emit(SocketEvent.MAP_CHARACTER_ATTACK)
|
gameStore.connection?.emit(SocketEvent.MAP_CHARACTER_ATTACK)
|
||||||
}
|
}
|
||||||
@ -57,36 +115,14 @@ export function useGameControlsComposable(scene: Phaser.Scene, layer: Phaser.Til
|
|||||||
function handleKeyUp(event: KeyboardEvent) {
|
function handleKeyUp(event: KeyboardEvent) {
|
||||||
pressedKeys.delete(event.key)
|
pressedKeys.delete(event.key)
|
||||||
|
|
||||||
// If no movement keys are pressed, clear the interval
|
if (pressedKeys.size === 0) {
|
||||||
if (pressedKeys.size === 0 && moveInterval) {
|
stopMovementLoop()
|
||||||
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
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const setupControls = () => {
|
const setupControls = () => {
|
||||||
|
updateCurrentPosition() // Initialize position
|
||||||
|
|
||||||
scene.input.on(Phaser.Input.Events.POINTER_DOWN, handlePointerDown)
|
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_MOVE, handlePointerMove)
|
||||||
scene.input.on(Phaser.Input.Events.POINTER_UP, handlePointerUp)
|
scene.input.on(Phaser.Input.Events.POINTER_UP, handlePointerUp)
|
||||||
@ -96,6 +132,9 @@ export function useGameControlsComposable(scene: Phaser.Scene, layer: Phaser.Til
|
|||||||
}
|
}
|
||||||
|
|
||||||
const cleanupControls = () => {
|
const cleanupControls = () => {
|
||||||
|
stopMovementLoop()
|
||||||
|
pressedKeys.clear()
|
||||||
|
|
||||||
scene.input.off(Phaser.Input.Events.POINTER_DOWN, handlePointerDown)
|
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_MOVE, handlePointerMove)
|
||||||
scene.input.off(Phaser.Input.Events.POINTER_UP, handlePointerUp)
|
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))
|
return Array.from({ length: height }, () => Array.from({ length: width }, () => tile))
|
||||||
}
|
}
|
||||||
|
|
||||||
export const calculateIsometricDepth = (positionX: number, positionY: number, pivotPoints: { x: number; y: number; }[] = []) => {
|
export const calculateIsometricDepth = (positionX: number, positionY: number, pivotPoints: { x: number; y: number }[] = []) => {
|
||||||
return Math.max(positionX + positionY);
|
return Math.max(positionX + positionY)
|
||||||
}
|
}
|
||||||
|
|
||||||
async function loadTileTextures(tiles: TileT[], scene: Phaser.Scene) {
|
async function loadTileTextures(tiles: TileT[], scene: Phaser.Scene) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user