Files
shadow-pixel-run/scripts/actors/player.gd
T

70 lines
2.1 KiB
GDScript

## player.gd
# Player character script. Handles input, pathfinding, and turn-based movement.
class_name Player
extends Character
# Movement speed in pixels per second.
const SPEED: float = 250.0
# Distance threshold for snapping to a tile (prevents jitter).
const ARRIVAL_THRESHOLD: float = 4.0
# 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
# 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)
_path = LevelManager.find_path(current_tile, clicked_tile)
# 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()
# 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 not _is_moving:
velocity = Vector2.ZERO
move_and_slide()
return
var to_target: Vector2 = _move_target - position
if to_target.length() < ARRIVAL_THRESHOLD:
position = _move_target
velocity = Vector2.ZERO
move_and_slide()
_is_moving = false
turn_finished.emit()
else:
velocity = to_target.normalized() * SPEED
move_and_slide()