diff --git a/src/components/game/character/Character.vue b/src/components/game/character/Character.vue index 56e86c4..26e67bb 100644 --- a/src/components/game/character/Character.vue +++ b/src/components/game/character/Character.vue @@ -45,12 +45,22 @@ const currentX = ref(0) const currentY = ref(0) const isometricDepth = ref(1) const isInitialPosition = ref(true) -const tween = ref(null) +const isMoving = ref(false) +let animationFrame: number | null = null +const moveSpeed = 5.7 const updateIsometricDepth = (x: number, y: number) => { isometricDepth.value = calculateIsometricDepth(x, y, 28, 94, true) } +const stopMovement = () => { + isMoving.value = false + if (animationFrame) { + cancelAnimationFrame(animationFrame) + animationFrame = null + } +} + const updatePosition = (x: number, y: number, direction: Direction) => { const targetX = tileToWorldX(props.tilemap, x, y) const targetY = tileToWorldY(props.tilemap, x, y) @@ -62,41 +72,42 @@ const updatePosition = (x: number, y: number, direction: Direction) => { return } - if (tween.value?.isPlaying()) { - tween.value.stop() + if (isMoving.value) { + stopMovement() } const distance = Math.sqrt(Math.pow(targetX - currentX.value, 2) + Math.pow(targetY - currentY.value, 2)) - if (distance >= config.tile_size.x / 1.1) { - currentX.value = targetX - currentY.value = targetY - return + isMoving.value = true + const startTime = performance.now() + const startX = currentX.value + const startY = currentY.value + const duration = distance * moveSpeed + + if (direction === Direction.POSITIVE) { + updateIsometricDepth(x, y) } - const duration = distance * 5.7 + const animate = (currentTime: number) => { + if (!isMoving.value) return - tween.value = props.tilemap.scene.tweens.add({ - targets: { x: currentX.value, y: currentY.value }, - x: targetX, - y: targetY, - duration, - ease: 'Linear', - onStart: () => { - if (direction === Direction.POSITIVE) { - updateIsometricDepth(x, y) - } - }, - onUpdate: (tween) => { - currentX.value = tween.targets[0].x - currentY.value = tween.targets[0].y - }, - onComplete: () => { + const elapsed = currentTime - startTime + const progress = Math.min(elapsed / duration, 1) + + currentX.value = startX + (targetX - startX) * progress + currentY.value = startY + (targetY - startY) * progress + + if (progress < 1) { + animationFrame = requestAnimationFrame(animate) + } else { + isMoving.value = false if (direction === Direction.NEGATIVE) { updateIsometricDepth(x, y) } } - }) + } + + animationFrame = requestAnimationFrame(animate) } const calcDirection = (oldX: number, oldY: number, newX: number, newY: number): Direction => { @@ -176,6 +187,6 @@ onMounted(() => { }) onUnmounted(() => { - tween.value?.stop() + stopMovement() }) - + \ No newline at end of file