Rework "Grid-based Navigation with Astar" demo

This commit is contained in:
Danil Alexeev
2023-02-27 13:38:45 +03:00
parent e03d6abbc8
commit 8ef5764b0d
7 changed files with 109 additions and 215 deletions

View File

@@ -1,61 +1,65 @@
extends Node2D
enum States { IDLE, FOLLOW }
enum State { IDLE, FOLLOW }
const MASS = 10.0
const ARRIVE_DISTANCE = 10.0
@export var speed: float = 200.0
var _state = States.IDLE
var _path = []
var _target_point_world = Vector2()
var _target_position = Vector2()
var _state = State.IDLE
var _velocity = Vector2()
@onready var _tile_map = $"../TileMap"
var _click_position = Vector2()
var _path = PackedVector2Array()
var _next_point = Vector2()
func _ready():
_change_state(States.IDLE)
_change_state(State.IDLE)
func _process(_delta):
if _state != States.FOLLOW:
if _state != State.FOLLOW:
return
var _arrived_to_next_point = _move_to(_target_point_world)
if _arrived_to_next_point:
var arrived_to_next_point = _move_to(_next_point)
if arrived_to_next_point:
_path.remove_at(0)
if len(_path) == 0:
_change_state(States.IDLE)
if _path.is_empty():
_change_state(State.IDLE)
return
_target_point_world = _path[0]
_next_point = _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) and get_parent().get_node("TileMap").check_start_position(global_mouse_pos):
global_position = global_mouse_pos
else:
_target_position = global_mouse_pos
_change_state(States.FOLLOW)
_click_position = get_global_mouse_position()
if _tile_map.is_point_walkable(_click_position):
if event.is_action_pressed(&"teleport_to", false, true):
_change_state(State.IDLE)
global_position = _tile_map.round_local_position(_click_position)
elif event.is_action_pressed(&"move_to"):
_change_state(State.FOLLOW)
func _move_to(world_position):
var desired_velocity = (world_position - position).normalized() * speed
func _move_to(local_position):
var desired_velocity = (local_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
return position.distance_to(local_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 _path.is_empty() or len(_path) == 1:
_change_state(States.IDLE)
if new_state == State.IDLE:
_tile_map.clear_path()
elif new_state == State.FOLLOW:
_path = _tile_map.find_path(position, _click_position)
if _path.size() < 2:
_change_state(State.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]
_next_point = _path[1]
_state = new_state