You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
114 lines
2.4 KiB
114 lines
2.4 KiB
extends Node
|
|
|
|
class_name Entity
|
|
|
|
var position: Vector2i
|
|
var global_speed = 10.0 # blocs per second
|
|
var id = -1
|
|
|
|
var moving_counter = 0
|
|
|
|
var path = []
|
|
var path_counter = 0
|
|
var following_path = false
|
|
|
|
signal moving
|
|
signal next_move
|
|
|
|
func _init(id: int, position: Vector2i):
|
|
self.id = id
|
|
self.position = position
|
|
next_move.connect(_path_continue)
|
|
|
|
func get_data():
|
|
var data = {
|
|
"id": self.id,
|
|
"position": self.position
|
|
}
|
|
|
|
return data
|
|
|
|
func move(new_position: Vector2i, speed: float):
|
|
emit_signal("moving", new_position, speed)
|
|
|
|
Global.world.blocs[position.x][position.y].entity = -1
|
|
self.position = new_position
|
|
position = new_position
|
|
Global.world.blocs[new_position.x][new_position.y].entity = id
|
|
|
|
var t = Timer.new()
|
|
t.wait_time = 1.0 / speed
|
|
t.set_one_shot(true)
|
|
t.autostart = true
|
|
Engine.get_main_loop().get_root().add_child(t)
|
|
await t.timeout
|
|
t.queue_free()
|
|
|
|
emit_signal("next_move")
|
|
|
|
func heuristic(a: Vector2i, b: Vector2i) -> float:
|
|
return abs(a.x - b.x) + abs(a.y - b.y)
|
|
|
|
func path_create(goal: Vector2i):
|
|
if goal == position:
|
|
path = []
|
|
return
|
|
|
|
if path.size():
|
|
if path[-1] == goal:
|
|
return
|
|
|
|
var frontier = []
|
|
var priorities = {}
|
|
var came_from = {}
|
|
var cost_so_far = {}
|
|
came_from[position] = null
|
|
cost_so_far[position] = 0
|
|
frontier.append(position)
|
|
|
|
while frontier.size():
|
|
var current = frontier.pop_front()
|
|
|
|
if current == goal:
|
|
break
|
|
|
|
for next in Global.world.neighbours(current):
|
|
var new_cost = cost_so_far[current] + Global.world.cost(current, next)
|
|
if next not in cost_so_far or new_cost < cost_so_far[next]:
|
|
cost_so_far[next] = new_cost
|
|
var priority = new_cost + heuristic(goal, next)
|
|
frontier.append(next)
|
|
priorities[next] = priority
|
|
came_from[next] = current
|
|
frontier.sort_custom(
|
|
func(a, b):
|
|
if priorities[a] < priorities[b]:
|
|
return true
|
|
return false
|
|
)
|
|
|
|
var current = goal
|
|
path = []
|
|
while current != position:
|
|
path.append(current)
|
|
current = came_from[current]
|
|
path.reverse()
|
|
path_counter = 0
|
|
|
|
func path_go_to(index):
|
|
var next = path[index]
|
|
var distance = sqrt(pow(next.x - position.x, 2) + pow(next.y - position.y, 2))
|
|
var speed = global_speed / distance
|
|
move(next, speed)
|
|
|
|
func path_start():
|
|
if not following_path and path.size():
|
|
following_path = true
|
|
path_go_to(0)
|
|
|
|
func _path_continue():
|
|
if path_counter < path.size() - 1 and following_path:
|
|
path_counter += 1
|
|
path_go_to(path_counter)
|
|
else:
|
|
following_path = false
|
|
|