=begin
Dijkstra寻路算法 By RyanBern
用法:在事件脚本中使用如下代码:
$game_player.dijkstra_move_to(x, y) #让主角移动到点(x, y)
$game_map.events[1].dijkstra_move_to(x, y) #让地图上的1号事件移动到点(x, y)
注意,如果点(x, y)无法达到,那么角色将不会移动
=end
module Dijkstra
class Point
attr_accessor :x
attr_accessor :y
def initialize(x, y)
@x = x
@y = y
end
end
def generate_move_route(final_x, final_y)
route = []
path = Table.new($game_map.width, $game_map.height)
queue = []
queue << Point.new(self.x, self.y)
path[self.x, self.y] = -1
if !$game_map.valid?(final_x, final_y) || self.x == final_x && self.y == final_y
return route
end
found = false
while(!queue.empty? && !found)
point = queue.shift
[2,4,6,8].each do |d|
new_x = point.x + (d == 6 ? 1 : d == 4 ? -1 : 0)
new_y = point.y + (d == 2 ? 1 : d == 8 ? -1 : 0)
if self.passable?(point.x, point.y, d) && path[new_x, new_y] == 0
queue << Point.new(new_x, new_y)
path[new_x, new_y] = d
found = true if new_x == final_x && new_y == final_y
end
end
end
if found
x = final_x
y = final_y
while(path[x, y] != -1)
d = path[x, y]
route << d
x -= (d == 6 ? 1 : d == 4 ? -1 : 0)
y -= (d == 2 ? 1 : d == 8 ? -1 : 0)
end
end
return route
end
def generate_move_command(route)
list = Array.new(route.size){|i| RPG::MoveCommand.new(route[route.size - 1 - i] / 2)}
list << RPG::MoveCommand.new(0)
commands = RPG::MoveRoute.new
commands.skippable = false
commands.repeat = false
commands.list = list
return commands
end
def dijkstra_move_to(x, y)
route = generate_move_route(x, y)
commands = generate_move_command(route)
self.force_move_route(commands)
end
end
class Game_Character
include Dijkstra
end