character.gd 1.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172
  1. extends Node2D
  2. const PathFindAStar = preload("./pathfind_astar.gd")
  3. enum State {
  4. IDLE,
  5. FOLLOW,
  6. }
  7. const MASS: float = 10.0
  8. const ARRIVE_DISTANCE: float = 10.0
  9. @export_range(10, 500, 0.1, "or_greater") var speed: float = 200.0
  10. var _state := State.IDLE
  11. var _velocity := Vector2()
  12. var _click_position := Vector2()
  13. var _path := PackedVector2Array()
  14. var _next_point := Vector2()
  15. @onready var _tile_map: PathFindAStar = $"../TileMap"
  16. func _ready() -> void:
  17. _change_state(State.IDLE)
  18. func _process(_delta: float) -> void:
  19. if _state != State.FOLLOW:
  20. return
  21. var arrived_to_next_point: bool = _move_to(_next_point)
  22. if arrived_to_next_point:
  23. _path.remove_at(0)
  24. if _path.is_empty():
  25. _change_state(State.IDLE)
  26. return
  27. _next_point = _path[0]
  28. func _unhandled_input(event: InputEvent) -> void:
  29. _click_position = get_global_mouse_position()
  30. if _tile_map.is_point_walkable(_click_position):
  31. if event.is_action_pressed(&"teleport_to", false, true):
  32. _change_state(State.IDLE)
  33. global_position = _tile_map.round_local_position(_click_position)
  34. elif event.is_action_pressed(&"move_to"):
  35. _change_state(State.FOLLOW)
  36. func _move_to(local_position: Vector2) -> bool:
  37. var desired_velocity: Vector2 = (local_position - position).normalized() * speed
  38. var steering: Vector2 = desired_velocity - _velocity
  39. _velocity += steering / MASS
  40. position += _velocity * get_process_delta_time()
  41. rotation = _velocity.angle()
  42. return position.distance_to(local_position) < ARRIVE_DISTANCE
  43. func _change_state(new_state: State) -> void:
  44. if new_state == State.IDLE:
  45. _tile_map.clear_path()
  46. elif new_state == State.FOLLOW:
  47. _path = _tile_map.find_path(position, _click_position)
  48. if _path.size() < 2:
  49. _change_state(State.IDLE)
  50. return
  51. # The index 0 is the starting cell.
  52. # We don't want the character to move back to it in this example.
  53. _next_point = _path[1]
  54. _state = new_state