Project1

标题: 【原创】事件寻路脚本(基于广度优先搜索和RGSS1) [打印本页]

作者: myownroc    时间: 2014-8-4 21:20
标题: 【原创】事件寻路脚本(基于广度优先搜索和RGSS1)
本帖最后由 myownroc 于 2014-8-5 17:01 编辑
旧版本

以下为最新版本
用法:在事件页中使用脚本,输入以下内容。
RUBY 代码复制
  1. BFS.find_path(character, target_x, target_y)

说明:
如果想要移动主角,character为$game_player;若想移动事件,character为$game_map.events[n] (注:n为相应事件的ID)
注意:该脚本适用于较小的地图(推荐不超过100*100)且工程的系统应基于默认的RGSS。
RUBY 代码复制下载
  1. module BFS
  2.   def self.find_path(character, tx, ty)
  3.     ox, oy = character.x, character.y
  4.     return if (tx > $game_map.width - 1) || (ty > $game_map.height - 1)
  5.     return if !($game_map.passable?(tx, ty, 0, character))
  6.     return if (tx == ox) && (ty == oy)
  7.     checked = []
  8.     father = []
  9.     for i in 0...$game_map.width
  10.       checked << []
  11.       father << []
  12.       for j in 0...$game_map.height
  13.         checked[-1] << 0
  14.         father[-1] << nil
  15.       end
  16.     end
  17.     path = []
  18.     found = false
  19.     checked[ox][oy] = 1
  20.     empty = false
  21.     loop do
  22.       empty = true
  23.       for i in 0...$game_map.width
  24.         for j in 0...$game_map.height
  25.           if checked[i][j] == 1
  26.             checked[i][j] = 2
  27.             if $game_map.passable?(i, j + 1, 2, character) &&
  28.               checked[i][j + 1] == 0
  29.               checked[i][j + 1] = 1
  30.               father[i][j + 1] = [i, j]
  31.             end
  32.             if $game_map.passable?(i - 1, j, 4, character) &&
  33.               checked[i - 1][j] == 0
  34.               checked[i - 1][j] = 1
  35.               father[i - 1][j] = [i, j]
  36.             end
  37.             if $game_map.passable?(i, j - 1, 8, character) &&
  38.               checked[i][j - 1] == 0
  39.               checked[i][j - 1] = 1
  40.               father[i][j - 1] = [i, j]
  41.             end
  42.             if $game_map.passable?(i + 1, j, 6, character) &&
  43.               checked[i + 1][j] == 0
  44.               checked[i + 1][j] = 1
  45.               father[i + 1][j] = [i, j]
  46.             end
  47.           end
  48.           if checked[tx][ty] == 1
  49.             found = true
  50.             break
  51.           end
  52.         end
  53.       end
  54.       for i in 0...$game_map.width
  55.         empty = false if checked[i].include?(1)
  56.       end
  57.       if found || empty
  58.         break
  59.       end
  60.     end
  61.     return if !found
  62.     if found
  63.       x, y = tx, ty
  64.       while [x, y] != [ox, oy]
  65.         dx, dy = father[x][y][0] - x, father[x][y][1] - y
  66.         step = 2 if dy == -1
  67.         step = 4 if dx == 1
  68.         step = 8 if dy == 1
  69.         step = 6 if dx == -1
  70.         path << step
  71.         x, y = father[x][y][0], father[x][y][1]
  72.       end
  73.       path.reverse!
  74.     end
  75.     list = []
  76.     path.each{|e|
  77.       code = 1 if e == 2
  78.       code = 2 if e == 4
  79.       code = 4 if e == 8
  80.       code = 3 if e == 6
  81.       list << RPG::MoveCommand.new(code)
  82.     }
  83.     list << RPG::MoveCommand.new(0)
  84.     skippable = false
  85.     repeat = false
  86.     commands = RPG::MoveRoute.new
  87.     commands.skippable = skippable
  88.     commands.repeat = repeat
  89.     commands.list = list
  90.     if character == nil
  91.       return true
  92.     end
  93.     character.force_move_route(commands)
  94.     return true
  95.   end
  96. end

如果还不能理解以上所述,可以下载附件进行考察。 FindPath.rar (192.79 KB, 下载次数: 389)
冲突评估(欢迎讨论):
双远景/三远景系统(预测,没有实验证据)
鼠标系统(预测,没有实验证据)
八方行走系统(预测,没有实验证据)
更新记录:
当前新版本比之前一个版本修正了绕路的bug。
提高了算法的效率。
作者: shy    时间: 2014-8-5 14:26
还不错~帮了大忙了~
作者: taroxd    时间: 2014-8-5 14:44
不直接整合进事件的移动路线-接近吗?

其实我挺喜欢禾西的A*脚本的,只给一个寻路的算法核心,整合这种东西交给用户。
作者: 羁绊的守望者    时间: 2014-8-12 19:24
哇哇,广度优先算法出来啦!
我准备写一个深度优先算法~
作者: end55rpg    时间: 2014-8-12 22:29
效率能说一下提高的量吗(貌似0.01s一张小地图)
,记得原来有个是障碍越多效率越快,不知LZ您的是不是这样(不清楚算法)
作者: end55rpg    时间: 2014-8-15 21:36
不太懂算法。。理解错误请见谅:
刚刚想了想这个算法,能否考虑
把不可通行标记为3或其他,交换
PASSABLE和标记==0的位置,在判断过的障碍那里就不必2次PASSABLE判断了
最主要,交换之后对于之前搜索过已经变为2标记的位置,将减少一次passable判断的多余
虽然到后面标记为2的已经减少了,但加起来的多余passble就很多了

另外初始化标记为0非要用循环吗- -b
作者: jiahui5592986    时间: 2014-9-7 12:07
LZ继续加油,争取把八方向的写好
作者: OCTSJimmy    时间: 2014-11-10 09:28
寻路算法也,楼主好牛!
记得原来有个whbm出的寻路算法,用了下也感觉好牛X。
作者: yang1zhi    时间: 2015-12-14 01:03
用条件分歧来设置多个目标点轮流走动时。
每当经过目标点,都会变卡




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