Project1

标题: 关于自动寻路的优化问题 [打印本页]

作者: Wind2010    时间: 2012-8-19 00:11
标题: 关于自动寻路的优化问题
本帖最后由 Wind2010 于 2012-8-19 00:13 编辑

目前自己在用whbm的八方向寻路脚本,但是不知道为啥当距离有点远的时候会很卡……
本来还打算做个隐身靠近+被攻击后瞬移的敌人的,玩家现在一看帧率就知道敌人离自己的远近了……
于是求解有没有方法让这个寻路脚本卡的帧数低点(不大于10fps我想玩家是看不出的- -)
PS:我目前做的游戏里只有少部分敌人有自动寻路,其他敌人用的都是傻瓜式跟踪,因此应该不存在多次寻路导致变卡

悬赏什么的,发现关闭问题不返还,于是决定等有最佳答案后再加悬赏

附:自己增加的敌人追踪部分:
  1.       if event.item.is_a?(L_ARPG_boss)
  2.         if (event.screen_x-to.screen_x)**2+(event.screen_y-to.screen_y)**2 >= 32**2
  3.           t_array = $find_path.find_short_path(event.x.to_i,event.y.to_i,to.x.to_i,to.y.to_i)
  4.           event.move_dr(t_array[0])
  5.         else
  6.           event.move_toward(to)
  7.         end
  8.       else
  9.         event.move_toward(to)
  10.       end

  11. #Game_Character
  12.   def move_dr(dr)
  13.     case dr
  14.     when 1
  15.       move_lower_left
  16.     when 2
  17.       move_down(true,false)
  18.     when 3
  19.       move_lower_right
  20.     when 4
  21.       move_left(true,false)
  22.     when 6
  23.       move_right(true,false)
  24.     when 7
  25.       move_upper_left
  26.     when 8
  27.       move_up(true,false)
  28.     when 9
  29.       move_upper_right
  30.     else
  31.       move_toward($game_player)
  32.     end
  33.   end
复制代码
像素行走脚本
寻路脚本:
  1. #==============================================================================
  2. # ■ Find_Path
  3. #------------------------------------------------------------------------------
  4. #  寻路算法
  5. #   By whbm
  6. =begin
  7. 使用find_short_path过程则需要传递起始坐标和目标坐标
  8. 例:$find_path = Find_Path.new
  9.    path = $find_path.find_short_path(起始X坐标,起始Y坐标,目标X坐标,目标Y坐标)
  10. =end
  11. #==============================================================================
  12. class Find_Path
  13. #--------------------------------------------------------------------------
  14. def initialize  #初始化
  15. @open_list = []
  16. @close_lise = []
  17. end  #结束初始化
  18. #--------------------------------------------------------------------------
  19. def fp_passable?(x, y, d)  #开始判定通行
  20. if [2, 4, 6, 8].include?(d)
  21.    if $game_player.passable?(x, y, d)
  22.      return true
  23.    else
  24.      return false
  25.    end
  26. else
  27.    case d
  28.    when 1
  29.      if ($game_player.passable?(x, y, 4) and
  30.        $game_player.passable?(x - 1, y, 2)) or
  31.         ($game_player.passable?(x, y, 2) and
  32.        $game_player.passable?(x, y + 1, 4))
  33.        return true
  34.      else
  35.        return false
  36.      end
  37.    when 3
  38.      if ($game_player.passable?(x, y, 6) and
  39.        $game_player.passable?(x + 1, y, 2)) or
  40.         ($game_player.passable?(x, y, 2) and
  41.        $game_player.passable?(x, y + 1, 6))
  42.        return true
  43.      else
  44.        return false
  45.      end
  46.    when 7
  47.      if ($game_player.passable?(x, y, 4) and
  48.        $game_player.passable?(x - 1, y, 8)) or
  49.         ($game_player.passable?(x, y, 8) and
  50.        $game_player.passable?(x, y - 1, 4))
  51.        return true
  52.      else
  53.        return false
  54.      end
  55.    when 9
  56.      if ($game_player.passable?(x, y, 6) and
  57.        $game_player.passable?(x + 1, y, 8)) or
  58.         ($game_player.passable?(x, y, 8) and
  59.        $game_player.passable?(x, y - 1, 6))
  60.        return true
  61.      else
  62.        return false
  63.      end
  64.    end
  65. end
  66. end  #结束判定通行
  67. #--------------------------------------------------------------------------
  68. def get_g(now_point)  #开始计算G值
  69. d = now_point[2]
  70. return 0 if d == 5
  71. father_point = get_father_point(now_point)
  72. g = father_point[3] + ((d == 1 or d == 3 or d == 7 or d == 9) ? 14 : 10)
  73. return g
  74. end  #结束计算G值
  75. #--------------------------------------------------------------------------
  76. def get_h(now_point)  #开始计算H值
  77. now_x = now_point[0]
  78. now_y = now_point[1]
  79. h = (@trg_x - now_x).abs + (@trg_y - now_y).abs
  80. return h
  81. end  #结束计算H值
  82. #--------------------------------------------------------------------------
  83. def get_f(now_point)  #开始计算F值
  84. return now_point[3] + now_point[4]
  85. end  #结束计算F值
  86. #--------------------------------------------------------------------------
  87. def get_point(x, y) #取已知坐标点
  88. if @open_list.size != 0
  89.    @open_list.each do |point|
  90.      if point[0] == x and point[1] == y
  91.        return point
  92.        break
  93.      end
  94.    end
  95. end
  96. if @close_list.size != 0
  97.    @close_list.each do |point|
  98.      if point[0] == x and point[1] == y
  99.        return point
  100.        break
  101.      end
  102.    end
  103. end
  104. end  #结束取已知坐标点
  105. #--------------------------------------------------------------------------
  106. def get_father_point(now_point)  #取已知点的父节点
  107. d = now_point[2]
  108. return now_point if d == 5
  109. x = now_point[0] + ((d == 9 or d == 6 or d == 3) ? 1 : ((d == 7 or d == 4 or d == 1) ? -1 : 0))
  110. y = now_point[1] + ((d == 1 or d == 2 or d == 3) ? 1 : ((d == 7 or d == 8 or d == 9) ? -1 : 0))
  111. return get_point(x, y)
  112. end  #结束取已知点的父节点
  113. #--------------------------------------------------------------------------
  114. def new_point(x, y, d)  #开始建立新节点
  115. #print x,y,d
  116. point = [x, y, d]
  117. point.push get_g(point)
  118. point.push get_h(point)
  119. point.push get_f(point)
  120. return point
  121. end  #结束建立新节点
  122. #--------------------------------------------------------------------------
  123. def find_short_path(self_x, self_y, trg_x, trg_y)  #开始搜索路径
  124. return [] if not (fp_passable?(trg_x, trg_y, 8) or
  125.                    fp_passable?(trg_x, trg_y, 4) or
  126.                    fp_passable?(trg_x, trg_y, 6) or
  127.                    fp_passable?(trg_x, trg_y, 2))
  128. @self_x = self_x
  129. @self_y = self_y
  130. @now_x = self_x
  131. @now_y = self_y
  132. @trg_x = trg_x
  133. @trg_y = trg_y
  134. @open_list = []
  135. @close_list = []
  136. #准备搜索
  137. #print @self_x,@self_y
  138. @now_point = new_point(@self_x, @self_y, 5) #令起始点为当前点
  139. @open_list.push @now_point #将当前点加入关闭列表
  140. #开始搜索
  141. loop do
  142.    check_trg = check_around_point(@now_point)
  143.    if check_trg == true
  144.      @path = get_path
  145.      break
  146.    end
  147.    @now_point = get_lowest_f_point
  148.    if @now_point == [] or @now_point == nil
  149.      @path = []
  150.      break
  151.    end
  152. end
  153. return @path
  154. end  #结束搜索路径
  155. #--------------------------------------------------------------------------
  156. def find_player_short_path(trg_x, trg_y)  #寻找角色的最短路径
  157. self_x = $game_player.x
  158. self_y = $game_player.y
  159. return find_short_path(self_x, self_y, trg_x, trg_y)
  160. end  #结束角色的寻找路径
  161. #--------------------------------------------------------------------------
  162. def get_path  #取得最终的路径
  163. path = []
  164. now_point = @open_list[@open_list.size - 1]
  165. path.push(10 - now_point[2])
  166. last_point = now_point
  167. loop do
  168.    now_point = get_father_point(now_point)
  169.    break if now_point[2] == 5
  170.    path.push(10 - now_point[2])
  171. end
  172. return path.reverse
  173. end  #结束取得最终的路径
  174. #--------------------------------------------------------------------------
  175. def get_lowest_f_point  #开始取得最低F值的点
  176. if @open_list == []
  177.    return []
  178. end
  179. last_lowest_f_point = @open_list[0]
  180. @open_list.each do |point|
  181.    last_lowest_f_point = point if point[5] < last_lowest_f_point[5]
  182. end
  183. return last_lowest_f_point
  184. end  #结束取得最低F值点
  185. #--------------------------------------------------------------------------
  186. def check_around_point(point)  #开始检查已知点的八方节点
  187. for d in [1, 2, 3, 4, 6, 7, 8, 9]
  188.    x = point[0] + ((d == 9 or d == 6 or d == 3) ? 1 : ((d == 7 or d == 4 or d == 1) ? -1 : 0))
  189.    y = point[1] + ((d == 1 or d == 2 or d == 3) ? 1 : ((d == 7 or d == 8 or d == 9) ? -1 : 0))
  190.    if in_close_list?(x, y) #在关闭列表中
  191.      next
  192.    elsif in_open_list?(x, y) #在开启列表中
  193.      get_new_g_point = new_point(x, y, 10 - d)
  194.      get_last_g_point = get_point(x, y)
  195.      if get_new_g_point[3] >= get_last_g_point[3]
  196.        next
  197.      else
  198.        #如果改变父节点是新G值更小则确定改变
  199.        @open_list[@open_list.index(get_last_g_point)] = get_new_g_point
  200.      end
  201.    else
  202.      if fp_passable?(point[0], point[1], d)
  203.        # 如果不在开启列表中、且不在关闭列表中、且通行则添加它到新八周节点
  204.        @open_list.push new_point(x, y, 10 - d)
  205.        #如果将目标点添加到了开启列表中就返回true
  206.        return true if x == @trg_x and y == @trg_y
  207.      end
  208.    end
  209. end
  210. #此刻没有找到目标点并将当前点加入关闭列表并在开启列表中删除
  211. @close_list.push point
  212. @open_list.delete(point)
  213. #此刻没找到目标点并返回false
  214. return false
  215. end  #结束计算已知点的八方节点
  216. #--------------------------------------------------------------------------
  217. def in_open_list?(x, y)  #开始检查谋点是否在开启列表中
  218. @open_list.each do |point|
  219.    return true if point[0] == x and point[1] == y
  220. end
  221. return false
  222. end  #结束检查谋点是否在开启列表中
  223. #--------------------------------------------------------------------------
  224. def in_close_list?(x, y)  #开始检查谋点是否在关闭列表中
  225. @close_list.each do |point|
  226.    return true if point[0] == x and point[1] == y
  227. end
  228. return false
  229. end  #结束检查谋点是否在关闭列表中
  230. #--------------------------------------------------------------------------
  231. end
  232. $find_path = Find_Path.new
复制代码
dsu_plus_rewardpost_czw
作者: Wind2010    时间: 2012-8-19 22:19
ORZ或者求个不太卡的寻路脚本,只需要能够找到应该前进的方向就可以了……




欢迎光临 Project1 (https://rpg.blue/) Powered by Discuz! X3.1