mirror of
https://github.com/godotengine/godot-demo-projects.git
synced 2026-01-05 10:09:47 +03:00
Some changes to Astar code
This commit is contained in:
@@ -1,60 +1,61 @@
|
||||
extends Position2D
|
||||
extends Node2D
|
||||
|
||||
enum States { IDLE, FOLLOW }
|
||||
|
||||
export(float) var speed = 200.0
|
||||
var _state = null
|
||||
|
||||
var path = []
|
||||
var target_point_world = Vector2()
|
||||
var target_position = Vector2()
|
||||
var _path = []
|
||||
var _target_point_world = Vector2()
|
||||
var _target_position = Vector2()
|
||||
|
||||
var velocity = Vector2()
|
||||
var _velocity = Vector2()
|
||||
|
||||
func _ready():
|
||||
_change_state(States.IDLE)
|
||||
|
||||
|
||||
func _process(_delta):
|
||||
if not _state == States.FOLLOW:
|
||||
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:
|
||||
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]
|
||||
_target_point_world = _path[0]
|
||||
|
||||
|
||||
func _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 = get_global_mouse_position()
|
||||
global_position = global_mouse_pos
|
||||
else:
|
||||
target_position = get_global_mouse_position()
|
||||
_target_position = global_mouse_pos
|
||||
_change_state(States.FOLLOW)
|
||||
|
||||
|
||||
func move_to(world_position):
|
||||
func _move_to(world_position):
|
||||
var MASS = 10.0
|
||||
var ARRIVE_DISTANCE = 10.0
|
||||
|
||||
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()
|
||||
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_path(position, target_position)
|
||||
if not path or len(path) == 1:
|
||||
_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]
|
||||
_target_point_world = _path[1]
|
||||
_state = new_state
|
||||
|
||||
@@ -4,7 +4,7 @@ const BASE_LINE_WIDTH = 3.0
|
||||
const DRAW_COLOR = Color.white
|
||||
|
||||
# The Tilemap node doesn't have clear bounds so we're defining the map's limits here.
|
||||
export(Vector2) var map_size = Vector2(16, 16)
|
||||
export(Vector2) var map_size = Vector2.ONE * 16
|
||||
|
||||
# The path start and end variables use setter methods.
|
||||
# You can find them at the bottom of the script.
|
||||
@@ -85,10 +85,11 @@ func astar_connect_walkable_cells(points_array):
|
||||
# left and bottom of it. If it's in the map and not an obstalce.
|
||||
# We connect the current point with it.
|
||||
var points_relative = PoolVector2Array([
|
||||
Vector2(point.x + 1, point.y),
|
||||
Vector2(point.x - 1, point.y),
|
||||
Vector2(point.x, point.y + 1),
|
||||
Vector2(point.x, point.y - 1)])
|
||||
point + Vector2.RIGHT,
|
||||
point + Vector2.LEFT,
|
||||
point + Vector2.DOWN,
|
||||
point + Vector2.UP,
|
||||
])
|
||||
for point_relative in points_relative:
|
||||
var point_relative_index = calculate_point_index(point_relative)
|
||||
if is_outside_map_bounds(point_relative):
|
||||
@@ -135,7 +136,7 @@ func is_outside_map_bounds(point):
|
||||
return point.x < 0 or point.y < 0 or point.x >= map_size.x or point.y >= map_size.y
|
||||
|
||||
|
||||
func _get_path(world_start, world_end):
|
||||
func get_astar_path(world_start, world_end):
|
||||
self.path_start_position = world_to_map(world_start)
|
||||
self.path_end_position = world_to_map(world_end)
|
||||
_recalculate_path()
|
||||
|
||||
Reference in New Issue
Block a user