pandemonium_demo_projects/2d/navigation_astar/character.gd

62 lines
1.5 KiB
GDScript3
Raw Normal View History

extends Node2D
enum States { IDLE, FOLLOW }
const MASS = 10.0
const ARRIVE_DISTANCE = 10.0
export(float) var speed = 200.0
var _state = States.IDLE
var _path = []
var _target_point_world = Vector2()
var _target_position = Vector2()
var _velocity = Vector2()
func _ready():
_change_state(States.IDLE)
func _process(_delta):
if _state != States.FOLLOW:
return
var _arrived_to_next_point = _move_to(_target_point_world)
if _arrived_to_next_point:
_path.remove(0)
if len(_path) == 0:
_change_state(States.IDLE)
return
_target_point_world = _path[0]
func _unhandled_input(event):
if event.is_action_pressed("click"):
var global_mouse_pos = get_global_mouse_position()
if Input.is_key_pressed(KEY_SHIFT):
global_position = global_mouse_pos
else:
_target_position = global_mouse_pos
_change_state(States.FOLLOW)
func _move_to(world_position):
var desired_velocity = (world_position - position).normalized() * speed
var steering = desired_velocity - _velocity
_velocity += steering / MASS
position += _velocity * get_process_delta_time()
rotation = _velocity.angle()
return position.distance_to(world_position) < ARRIVE_DISTANCE
func _change_state(new_state):
if new_state == States.FOLLOW:
_path = get_parent().get_node("TileMap").get_astar_path(position, _target_position)
if not _path or len(_path) == 1:
_change_state(States.IDLE)
return
# The index 0 is the starting cell.
# We don't want the character to move back to it in this example.
_target_point_world = _path[1]
_state = new_state