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.
 
Gridmap/scripts/Entity.gd

137 lines
2.9 KiB

extends Node
class_name Entity
var position: Vector2i
var global_speed = 3.0 # blocs per second
var id = -1
var moving_counter = 0
var path = []
var path_counter = 0
var following_path = false
enum states {
IDLE,
WALK
}
var state = states.IDLE
signal changed_state
signal moving
signal next_move
func _init(id: int, position: Vector2i):
self.id = id
self.position = position
next_move.connect(_path_continue)
set_state(states.IDLE)
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:
var dx = abs(a.x - b.x)
var dy = abs(a.y - b.y)
var xx = min(dx, Global.world.width - dx)
var yy = min(dy, Global.world.width - dy)
return xx + yy
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 vec_distance = Global.world.vec_distance(position, next)
var distance = sqrt(pow(vec_distance.x, 2) + pow(vec_distance.y, 2))
var speed = global_speed / distance
move(next, speed)
func path_start():
if not following_path and path.size():
following_path = true
set_state(states.WALK)
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:
set_state(states.IDLE)
following_path = false
func set_state(new_state):
state = new_state
emit_signal("changed_state", state)
func get_height():
return Global.world.get_height(position)