mirror of
https://github.com/godotengine/godot-demo-projects.git
synced 2026-01-06 14:10:55 +03:00
Rework "Grid-based Navigation with Astar" demo
This commit is contained in:
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user