class Game_Map
#--------------------------------------------------------------------------
def distance(x1, y1, x2, y2)
return delta_x(x1, x2).abs + delta_y(y1, y2).abs
end
#--------------------------------------------------------------------------
def loop_horizontal?
return false
end
#--------------------------------------------------------------------------
def loop_vertical?
return false
end
#--------------------------------------------------------------------------
def delta_x(x1, x2)
result = x1 - x2
if loop_horizontal? && result.abs > width / 2
result += result < 0 ? width : -width
end
return result
end
#--------------------------------------------------------------------------
def delta_y(y1, y2)
result = y1 - y2
if loop_vertical? && result.abs > height / 2
result += result < 0 ? height : -height
end
return result
end
end #class
class Game_Character
alias xr_mv_initialize initialize
def initialize
xr_mv_initialize
@search_limit = 15
end
#--------------------------------------------------------------------------
def delta_x_from(x)
return $game_map.delta_x(@x, x)
end
#--------------------------------------------------------------------------
def delta_y_from(y)
return $game_map.delta_y(@y, y)
end
#--------------------------------------------------------------------------
def find_direction(x, y)
$hi = $hi + 1
#貌似$hi是测试用
# pst"#{$hi}"
return 0 if @x == x && @y == y
goal_x = x; goal_y = y
map_width = $game_map.width
node_list = []; open_list = []; closed_list = []
start = {}; best = start
start[:parent] = nil; start[:x] = @x; start[:y] = @y; start[:g] = 0
#start[:xr] = $game_map.distance(start[:x], start[:y], goal_x, goal_y);
start[:xr] = $game_map.distance(@x, @y, goal_x, goal_y);
node_list.push(start)
open_list.push(start[:y] * map_width + start[:x])
t = 0 #t若大于1则可寻路到达目标,因此用来判断用
while node_list.size > 0
best_index = 0
node_list.size.times do |i|
best_index = i if node_list[i][:xr] < node_list[best_index][:xr]
end
current = node_list[best_index]
x1 = current[:x]; y1 = current[:y]
pos1 = y1 * map_width + x1
g1 = current[:g]
node_list.delete(current)
open_list.delete(pos1)
closed_list << pos1
if current[:x] == goal_x && current[:y] == goal_y
#到达了目的地返回
#补充:t若大于1则可寻路到达目标,因此用来判断用
t += 1
best = current
#pst"no"
break
else
#注:会运行多次, 即使到达目标也要运行,因些不要返回,若返回只會运行一次
#return
end
next if g1 >= @search_limit
4.times do |j|
direction = 2 + j * 2
x2 = x1 + (direction == 6 ? 1 : direction == 4 ? -1 : 0)
y2 = y1 + (direction == 2 ? 1 : direction == 8 ? -1 : 0)
pos2 = y2 * map_width + x2
next if closed_list.include?(pos2) || !passable?(x1, y1, direction)
g2 = g1 + 1
index2 = open_list.index(pos2)
if index2 == nil || g2 < node_list[index2][:g]
if index2 != nil
neighbor = node_list[index2]
else
neighbor = {}; node_list << neighbor; open_list << pos2
end
neighbor[:parent] = current
neighbor[:x] = x2
neighbor[:y] = y2
neighbor[:g] = g2
neighbor[:xr] = g2 + $game_map.distance(x2, y2, goal_x, goal_y)
if !best || neighbor[:xr] - neighbor[:g] < best[:xr] - best[:g]
best = neighbor
end
end
end
end
node = best
while node[:parent] && node[:parent] != start
node = node[:parent]
end
delta_x1 = $game_map.delta_x(node[:x], start[:x])
delta_y1 = $game_map.delta_y(node[:y], start[:y])
if delta_y1 > 0
#以下像之前测试用的,无视,
#貌似当初始为下了泡后让怪不移动返回333,但后来好像不用
#因该游戏作者使用了泡泡以地形标志为七实际也是地形,站在泡泡上面就怪寻不到自己
#if @泡泡禁止通行方向 == "下"
#@对泡原地思考时间_v = 30
#return 0,333
#end #if
return 2 ,t
#返回方向以及是否移动,t若大于1则可寻路到达目标,因此用来判断用
#分别为:2下,4左,6右,8上
#(一次只移动一格)
elsif delta_x1 < 0
#if @泡泡禁止通行方向 == "左"
#@对泡原地思考时间_v = 30
#return 0,333
#end #if
return 4 ,t
elsif delta_x1 > 0
# if @泡泡禁止通行方向 == "右"
#@对泡原地思考时间_v = 30
# return 0,333
# end #if
return 6 ,t
elsif delta_y1 < 0
# if @泡泡禁止通行方向 == "上"
#@对泡原地思考时间_v = 30
#return 0,333
# end #if
return 8 ,t
end
delta_x2 = delta_x_from(goal_x)
delta_y2 = delta_y_from(goal_y)
if delta_x2.abs > delta_y2.abs
return delta_x2 > 0 ? 4 : 6 ,t
elsif delta_y2 != 0
return delta_y2 > 0 ? 8 : 2 ,t
end
return 0
end
end #class Game_Character