character.gd 1.6 KB

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