feat: Enhance player movement and turn management system
This commit is contained in:
+38
-10
@@ -1,5 +1,5 @@
|
||||
## player.gd
|
||||
# Player character script. Handles input, pathfinding, and movement.
|
||||
# Player character script. Handles input, pathfinding, and turn-based movement.
|
||||
class_name Player
|
||||
extends Character
|
||||
|
||||
@@ -8,13 +8,28 @@ const SPEED: float = 250.0
|
||||
# Distance threshold for snapping to a tile (prevents jitter).
|
||||
const ARRIVAL_THRESHOLD: float = 4.0
|
||||
|
||||
|
||||
# The current path (as a list of tile coordinates) the player is following.
|
||||
# The queued path (tile coordinates) the player will walk along.
|
||||
var _path: Array[Vector2i] = []
|
||||
# True when the TurnManager is waiting for the player to act.
|
||||
var _awaiting_input: bool = false
|
||||
# True while the player is animating toward _move_target.
|
||||
var _is_moving: bool = false
|
||||
# World position of the tile the player is currently stepping toward.
|
||||
var _move_target: Vector2 = Vector2.ZERO
|
||||
|
||||
|
||||
# Handles mouse input for movement. Calculates a path to the clicked tile.
|
||||
# Called by TurnManager at the start of the player's turn.
|
||||
func take_turn() -> void:
|
||||
if _path.is_empty():
|
||||
_awaiting_input = true
|
||||
else:
|
||||
_start_step()
|
||||
|
||||
|
||||
# Handles mouse input for movement. Only active while awaiting input.
|
||||
func _unhandled_input(event: InputEvent) -> void:
|
||||
if not _awaiting_input:
|
||||
return
|
||||
if event is InputEventMouseButton and event.button_index == MOUSE_BUTTON_LEFT and event.pressed:
|
||||
var clicked_tile: Vector2i = LevelManager.world_to_tile(get_global_mouse_position())
|
||||
var current_tile: Vector2i = LevelManager.world_to_tile(position)
|
||||
@@ -22,20 +37,33 @@ func _unhandled_input(event: InputEvent) -> void:
|
||||
# Drop the first entry — it's the tile the player is already on.
|
||||
if not _path.is_empty():
|
||||
_path.remove_at(0)
|
||||
if not _path.is_empty():
|
||||
_start_step()
|
||||
|
||||
# Moves the player along the path, one tile at a time, using velocity.
|
||||
|
||||
# Begins movement toward the next tile in the queued path.
|
||||
func _start_step() -> void:
|
||||
_awaiting_input = false
|
||||
_is_moving = true
|
||||
var next_tile: Vector2i = _path.pop_front()
|
||||
_move_target = LevelManager.tile_to_world(next_tile)
|
||||
|
||||
|
||||
# Moves the player toward _move_target each frame. Emits turn_finished on arrival.
|
||||
func _physics_process(_delta: float) -> void:
|
||||
if _path.is_empty():
|
||||
if not _is_moving:
|
||||
velocity = Vector2.ZERO
|
||||
move_and_slide()
|
||||
return
|
||||
|
||||
var target_world: Vector2 = LevelManager.tile_to_world(_path[0])
|
||||
var to_target: Vector2 = target_world - position
|
||||
var to_target: Vector2 = _move_target - position
|
||||
|
||||
if to_target.length() < ARRIVAL_THRESHOLD:
|
||||
position = target_world
|
||||
_path.remove_at(0)
|
||||
position = _move_target
|
||||
velocity = Vector2.ZERO
|
||||
move_and_slide()
|
||||
_is_moving = false
|
||||
turn_finished.emit()
|
||||
else:
|
||||
velocity = to_target.normalized() * SPEED
|
||||
move_and_slide()
|
||||
|
||||
Reference in New Issue
Block a user