设为首页收藏本站|繁體中文

Project1

 找回密码
 注册会员
搜索
查看: 2921|回复: 2
打印 上一主题 下一主题

[RMVA发布] RMVA A+自动寻路 系统(应该不算原创

[复制链接]

Lv1.梦旅人

梦石
0
星屑
120
在线时间
68 小时
注册时间
2007-12-16
帖子
75
跳转到指定楼层
1
发表于 2012-8-15 21:44:56 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式

加入我们,或者,欢迎回来。

您需要 登录 才可以下载或查看,没有帐号?注册会员

x
这脚本其实只是把之前神隐不器VX上发的A*自动寻路二叉堆版
实装到VA的地图上而已
然后修正了一下地图循环的部分~~~

这算是伪八方向的版本
如果要改四方向就把
11行
RUBY 代码复制
  1. Directions = 8 # 寻路方向(4或8)

改成
RUBY 代码复制
  1. Directions = 4 # 寻路方向(4或8)

334~337行
RUBY 代码复制
  1.     if Input.dir8 > 0
  2.       init_mouse_control_info
  3.       move_direction(Input.dir8)
  4.     end

改成
RUBY 代码复制
  1.     if Input.dir4 > 0
  2.       init_mouse_control_info
  3.       move_direction(Input.dir4)
  4.     end

401~428行
RUBY 代码复制
  1. if @mouse_drag
  2.       @mpath.clear unless @mpath.empty?
  3.       dir = -1
  4.       # 滑鼠移動控制
  5.       dir = 6 if mouse_x > self.screen_x + 30
  6.       dir = 4 if mouse_x < self.screen_x - 30
  7.       if mouse_y > self.screen_y + 10
  8.         case dir
  9.         when 4
  10.           dir = 1
  11.         when 6
  12.           dir = 3
  13.         else
  14.           dir = 2
  15.         end
  16.       end
  17.       if mouse_y < self.screen_y - 48
  18.         case dir
  19.         when 4
  20.           dir = 7
  21.         when 6
  22.           dir = 9
  23.         else
  24.           dir = 8
  25.         end
  26.       end
  27.       move_direction(dir) if dir > 0
  28.     end

改成
RUBY 代码复制
  1. if @mouse_drag
  2.       @mpath.clear unless @mpath.empty?
  3.       dir = -1
  4.       # 滑鼠移動控制
  5.       dir = 6 if mouse_x > self.screen_x + 30
  6.       dir = 4 if mouse_x < self.screen_x - 30
  7.       dir = 2 if mouse_y > self.screen_y + 10
  8.       dir = 8 if mouse_y < self.screen_y - 48
  9.       move_direction(dir) if dir > 0
  10.     end



要用真八方向的话就自己改
Game_Player的move_direction(d)方法吧

RUBY 代码复制
  1. #==============================================================================
  2. # ■ RMVA A+自动寻路 系统
  3. #------------------------------------------------------------------------------
  4. #  A*自動尋路 部分 By 神隱不器
  5. #     其他腳本 部分 By 釣到一隻猴子@_@
  6. #==============================================================================
  7.  
  8. #==============================================================================
  9. # ■ PathFinding
  10. #------------------------------------------------------------------------------
  11. #  A*自動尋路 二叉堆版。
  12. #     By 神隱不器
  13. #==============================================================================
  14.  
  15. module PathFinding
  16.   #--------------------------------------------------------------------------
  17.   # ● 参数
  18.   #--------------------------------------------------------------------------
  19.   Directions = 8  # 寻路方向(4或8)
  20.   PathType = 1    # 返回值的类型(0:节点坐标, 1:移动方向)
  21.   #--------------------------------------------------------------------------
  22.   Node = Struct.new(:x, :y, :d, :parent, :h, :g, :f)
  23.   #--------------------------------------------------------------------------
  24.   # ● 搜索路径
  25.   #--------------------------------------------------------------------------
  26.   def self.find_short_path(self_x, self_y, trg_x, trg_y)
  27.     return find_path(self_x, self_y, trg_x, trg_y)
  28.   end
  29.   #--------------------------------------------------------------------------
  30.   # ● 寻找角色的最短路径
  31.   #--------------------------------------------------------------------------
  32.   def self.find_player_short_path(trg_x, trg_y)
  33.     if Input.mouse_icon != 0
  34.       @possible_x = trg_x
  35.       @possible_y = trg_y
  36.     end
  37.     self_x = $game_player.x
  38.     self_y = $game_player.y
  39.     return find_path(self_x, self_y, trg_x, trg_y)
  40.   end
  41.   #--------------------------------------------------------------------------
  42.   # ● 开始
  43.   #--------------------------------------------------------------------------
  44.   def self.find_path(start_x, start_y, dest_x, dest_y)
  45.     @dest_pos = [dest_x, dest_y]
  46.     ## 加入起始节点
  47.     size = [$game_map.width, $game_map.height]
  48.     @open = BinaryHeap.new(size, make_node(start_x, start_y, nil)) {|a,b| a.f <=> b.f }
  49.     @link = @open.link
  50.     path = []
  51.     while !@open.data.empty?
  52.       node = @open.dequeue
  53.       if [node.x,node.y] == @dest_pos
  54.         path = make_path(node,PathType)
  55.         break
  56.       end
  57.       self.check(node)
  58.     end
  59.     @possible_x = nil
  60.     @possible_y = nil
  61.     return path
  62.   end
  63.   #--------------------------------------------------------------------------
  64.   # ● 生成路径
  65.   # type: 返回的形式 (0:节点坐标, 1:移动方向)
  66.   #--------------------------------------------------------------------------
  67.   def self.make_path(node,type)
  68.     path = []
  69.     loop do
  70.       case type
  71.       when 0
  72.         path.unshift [node.x, node.y]
  73.       when 1
  74.         path.unshift direction(node.x,node.y,node.parent)
  75.       end
  76.       ## 循环条件
  77.       node = node.parent
  78.       break if node.nil? || node.parent.nil?
  79.     end
  80.     return path
  81.   end
  82.   #--------------------------------------------------------------------------
  83.   # ● 生成节点
  84.   #--------------------------------------------------------------------------
  85.   def self.make_node(x, y, parent)
  86.     buf = Node.new(x,y,direction(x,y,parent),parent)
  87.     buf.h = self.h(buf)
  88.     buf.g = self.g(buf)
  89.     buf.f = buf.h + buf.g
  90.     return buf
  91.   end
  92.   #--------------------------------------------------------------------------
  93.   # ● 寻路
  94.   #--------------------------------------------------------------------------
  95.   def self.check(node)
  96.     px = $game_map.round_x(node.x)
  97.     py = $game_map.round_y(node.y)
  98.     @link[px, py] = -2 ## closed
  99.     self.child_nodes(node).each do |n|
  100.       x = $game_map.round_x(n.x)
  101.       y = $game_map.round_y(n.y)
  102.       next if @link[x, y] == -2 ## closed
  103.       next if !passable?(px, py, n.d)
  104.       ## 检查更新
  105.       if @link[x, y] - 1 >= 0 && @open.data[@link[x, y] - 1]
  106.         @open.replace(@link[x, y] - 1, n) if @open.data[@link[x, y] - 1].g > n.g
  107.       else
  108.         @open.enqueue(n)
  109.       end
  110.     end
  111.   end
  112.   #--------------------------------------------------------------------------
  113.   # ● h值
  114.   #--------------------------------------------------------------------------
  115.   def self.h(node)
  116.     return ((node.x-@dest_pos[0]).abs + (node.y-@dest_pos[1]).abs)*20
  117.   end
  118.   #--------------------------------------------------------------------------
  119.   # ● g值
  120.   #--------------------------------------------------------------------------
  121.   def self.g(node)
  122.     parent = node.parent
  123.     return 0 if parent.nil?
  124.     dg = parent.d == node.d ? 0 : 14
  125.                                   ## 改变方向的附加开销
  126.     dx = node.x - parent.x
  127.     dy = node.y - parent.y
  128.     ## 判断相对坐标
  129.     if dx != 0 && dy != 0
  130.       return parent.g + 14 + dg
  131.     else
  132.       return parent.g + 10 + dg
  133.     end
  134.   end
  135.   #--------------------------------------------------------------------------
  136.   # ● 方向
  137.   #--------------------------------------------------------------------------
  138.   def self.direction(x,y,parent)
  139.     return parent.nil? ? 5 : (5 + (x-parent.x)*1 + (y-parent.y)*-3)
  140.   end
  141.   #--------------------------------------------------------------------------
  142.   # ● 子节点
  143.   #--------------------------------------------------------------------------
  144.   def self.child_nodes(node)
  145.     nodes = []
  146.     case Directions
  147.     when 4 # 4方向寻路
  148.       nodes<<make_node(node.x,node.y-1,node)<<make_node(node.x,node.y+1,node)
  149.       nodes<<make_node(node.x-1,node.y,node)<<make_node(node.x+1,node.y,node)
  150.     when 8 # 8方向寻路
  151.       for x in -1..1
  152.         for y in -1..1
  153.           next if x == 0 && y == 0
  154.           nodes << make_node(node.x+x, node.y+y, node)
  155.         end
  156.       end
  157.     end
  158.     return nodes
  159.   end
  160.   #--------------------------------------------------------------------------
  161.   # ● 通行?
  162.   #--------------------------------------------------------------------------
  163.   def self.passable?(x, y, d)
  164.     if @possible_x and @possible_y
  165.       tx, ty = x, y
  166.       case d
  167.       when 1 # 左下
  168.         tx -= 1
  169.         ty += 1
  170.       when 2 # 下
  171.         ty += 1
  172.       when 3 # 右下
  173.         tx += 1
  174.         ty += 1
  175.       when 4 # 左
  176.         tx -= 1
  177.       when 6 # 右
  178.         tx += 1
  179.       when 7 # 左上
  180.         tx -= 1
  181.         ty -= 1
  182.       when 8 # 上
  183.         ty -= 1
  184.       when 9 # 右上
  185.         tx += 1
  186.         ty -= 1
  187.       end
  188.       return true if @possible_x == tx and @possible_y == ty
  189.     end
  190.     x = $game_map.round_x(x)
  191.     y = $game_map.round_y(y)
  192.     case d
  193.     when 0, 2, 4, 6, 8
  194.       return $game_player.passable?(x, y, d)
  195.     when 1
  196.       return $game_player.diagonal_passable?(x, y, 4, 2)
  197.     when 3
  198.       return $game_player.diagonal_passable?(x, y, 6, 2)
  199.     when 7
  200.       return $game_player.diagonal_passable?(x, y, 4, 8)
  201.     when 9
  202.       return $game_player.diagonal_passable?(x, y, 6, 8)
  203.     end
  204.   end
  205.   #--------------------------------------------------------------------------
  206.   # ●
  207.   #--------------------------------------------------------------------------
  208.   def self.open
  209.     @open.data
  210.   end
  211.   #--------------------------------------------------------------------------
  212.   # ●
  213.   #--------------------------------------------------------------------------
  214.   def self.close
  215.     result = []
  216.     for i in [email]0...@link.xsize[/email]
  217.       for j in [email]0...@link.ysize[/email]
  218.         result<<[i,j] if @link[i,j]==-2
  219.       end
  220.     end
  221.     return result
  222.   end
  223. end
  224.  
  225. #==============================================================================
  226. # ■ BinaryHeap
  227. #------------------------------------------------------------------------------
  228. #  二叉堆 寻路用。
  229. #==============================================================================
  230.  
  231. class BinaryHeap
  232.   #--------------------------------------------------------------------------
  233.   # ● 定义实例变量
  234.   #--------------------------------------------------------------------------
  235.   attr_reader :data
  236.   attr_reader :link
  237.   #--------------------------------------------------------------------------
  238.   # ● 初始化
  239.   #--------------------------------------------------------------------------
  240.   def initialize(link,*val,&cmp)
  241.     @link = Table.new(*link)
  242.     @data = val.sort
  243.     @cmp = cmp
  244.     @cmp = Proc.new{|a,b| a<=>b} if @cmp.nil?
  245.     @data.each_index{|i| @link[@data[i].x,@data[i].y] = i+1}
  246.   end
  247.   #--------------------------------------------------------------------------
  248.   # ● 入列
  249.   #--------------------------------------------------------------------------
  250.   def enqueue(val)
  251.     return replace(@data.size,val)
  252.   end
  253.   #--------------------------------------------------------------------------
  254.   # ● 出列
  255.   #--------------------------------------------------------------------------
  256.   def dequeue
  257.     shift = @data[0]
  258.     if @data.size <= 1
  259.       @data.clear
  260.       return shift
  261.     end
  262.     @data[0] = @data.pop
  263.     linkto(0)
  264.     fid,cid = 0,[1,2]
  265.     while @data[cid[0]]     ## 左枝存在时
  266.       if @data[cid[1]].nil? ## 右枝不存在时
  267.         min = cid[0]
  268.       else
  269.         min = @cmp.call(@data[cid[0]],@data[cid[1]]) < 0 ? cid[0] : cid[1]
  270.       end
  271.       if @cmp.call(@data[min],@data[fid]) < 0
  272.         @data[min],@data[fid] = @data[fid],@data[min]
  273.         linkto(min,fid)
  274.         fid = min
  275.         cid = [fid*2+1,fid*2+2]
  276.       else
  277.         break
  278.       end
  279.     end
  280.     return shift
  281.   end
  282.   #--------------------------------------------------------------------------
  283.   # ● 修改
  284.   #--------------------------------------------------------------------------
  285.   def replace(pos, val)
  286.     @data[pos] = val
  287.     linkto(pos)
  288.     cid,fid = pos,(pos-1)/2
  289.     while cid > 0 ## 大于顶层时
  290.       if @cmp.call(val,@data[fid]) < 0
  291.         @data[cid] = @data[fid]
  292.         linkto(cid)
  293.         cid = fid
  294.         fid = (cid-1)/2
  295.       else
  296.         break
  297.       end
  298.     end
  299.     @data[cid] = val
  300.     linkto(cid)
  301.     return cid
  302.   end
  303.   #--------------------------------------------------------------------------
  304.   # ● 关联
  305.   #--------------------------------------------------------------------------
  306.   def linkto(*id)
  307.     id.each{|i| @link[@data[i].x,@data[i].y]=i+1}
  308.   end
  309. end
  310.  
  311. #==============================================================================
  312. # ■ Game_Player
  313. #------------------------------------------------------------------------------
  314. #  处理玩家人物的类。拥有事件启动的判定、地图的卷动等功能。
  315. #   本类的实例请参考 $game_player 。
  316. #==============================================================================
  317.  
  318. class Game_Player < Game_Character
  319.   #--------------------------------------------------------------------------
  320.   # ● 初始化对象
  321.   #--------------------------------------------------------------------------
  322.   alias :d8_ori_init :initialize unless defined? d8_ori_init
  323.   def initialize
  324.     d8_ori_init
  325.     init_mouse_control_info
  326.   end
  327.   #--------------------------------------------------------------------------
  328.   # ● 初始化滑鼠訊息
  329.   #--------------------------------------------------------------------------
  330.   def init_mouse_control_info
  331.     @mouse_drag = false
  332.     @mouse_count = 0
  333.     @mouse_speeding = false
  334.     @find_path = 0
  335.     @mpath ? @mpath.clear : @mpath = []
  336.   end
  337.   #--------------------------------------------------------------------------
  338.   # ● 由玩家控制移动
  339.   #--------------------------------------------------------------------------
  340.   def move_by_input
  341.     return if !movable? || $game_map.interpreter.running?
  342.     if Input.dir8 > 0
  343.       init_mouse_control_info
  344.       move_direction(Input.dir4)
  345.     end
  346.     update_mouse_control
  347.   end
  348.   #--------------------------------------------------------------------------
  349.   # ● 更新滑鼠控制
  350.   #--------------------------------------------------------------------------
  351.   def update_mouse_control
  352.     # Count refresh
  353.     @find_path += 1 if @find_path != 0
  354.     # Mouse
  355.     mouse_x, mouse_y = Input.get_mouse_pos
  356.     # 滑鼠連點狀態
  357.     if Input.dbclick?(Input::M_L)
  358.       @mouse_speeding = true
  359.       @find_path = 1
  360.       @mouse_count = 0
  361.     elsif Input.trigger?(Input::M_L)
  362.       @find_path = 1
  363.       @mouse_count = 0
  364.     elsif Input.press?(Input::M_L)
  365.       if @mouse_count > 10
  366.         @mouse_drag = true
  367.         @find_path = 0
  368.       else
  369.         @mouse_count += 1
  370.       end
  371.     else
  372.       @mouse_count = 0
  373.       @mouse_speeding = false if @mpath.empty? and @find_path == 0
  374.       @mouse_drag = false
  375.     end
  376.     # 自動尋路
  377.     if @find_path > 12
  378.       @find_path = 0
  379.       if Input.mouse_icon != 0
  380.         if @target_target_event != 0
  381.           @mouse_trigger_event = false
  382.           @target_target_event = 0
  383.         else
  384.           @mouse_trigger_event = true
  385.           @target_target_event = @target_event
  386.         end
  387.       end
  388.       # 計算滑鼠所在地圖座標
  389.       if $game_map.loop_horizontal? and $game_map.display_x + Graphics.width / 32 > $game_map.width and x < $game_map.display_x
  390.         dx = $game_map.display_x - $game_map.width
  391.       else
  392.         dx = $game_map.display_x
  393.       end
  394.       if $game_map.loop_vertical? and $game_map.display_y + Graphics.height / 32 > $game_map.height and y < $game_map.display_y
  395.         dy = $game_map.display_y - $game_map.height
  396.       else
  397.         dy = $game_map.display_y
  398.       end
  399.       mx = dx + mouse_x / 32
  400.       my = dy + mouse_y / 32
  401.       mx = mx <= mx.floor + 0.5 ? mx.ceil : mx.floor
  402.       my = my >= my.floor + 0.5 ? my.ceil : my.floor
  403.       if passable?(mx, my, 0) or Input.mouse_icon != 0
  404.         @mpath = PathFinding.find_player_short_path(mx, my)
  405.         @mouse_drag = false
  406.       end
  407.     end
  408.     if @mouse_drag
  409.       @mpath.clear unless @mpath.empty?
  410.       dir = -1
  411.       # 滑鼠移動控制
  412.       dir = 6 if mouse_x > self.screen_x + 30
  413.       dir = 4 if mouse_x < self.screen_x - 30
  414.       if mouse_y > self.screen_y + 10
  415.         case dir
  416.         when 4
  417.           dir = 1
  418.         when 6
  419.           dir = 3
  420.         else
  421.           dir = 2
  422.         end
  423.       end
  424.       if mouse_y < self.screen_y - 48
  425.         case dir
  426.         when 4
  427.           dir = 7
  428.         when 6
  429.           dir = 9
  430.         else
  431.           dir = 8
  432.         end
  433.       end
  434.       move_direction(dir) if dir > 0
  435.     end
  436.     # 依自動尋路路徑行走
  437.     move_direction(@mpath.shift) if !@mpath.empty?
  438.   end
  439.   #--------------------------------------------------------------------------
  440.   # ● 依方向移動
  441.   #--------------------------------------------------------------------------
  442.   def move_direction(d)
  443.     case d
  444.     when 2, 4, 6, 8
  445.       move_straight(d)
  446.     # 斜向需作修正
  447.     when 1
  448.       return move_diagonal(4, 2) if diagonal_passable?(@x, @y, 4, 2)
  449.       move_straight(4) if passable?(@x, @y, 4)
  450.       move_straight(2) if passable?(@x, @y, 2)
  451.     when 3
  452.       return move_diagonal(6, 2) if diagonal_passable?(@x, @y, 6, 2)
  453.       move_straight(6) if passable?(@x, @y, 6)
  454.       move_straight(2) if passable?(@x, @y, 2)
  455.     when 7
  456.       return move_diagonal(4, 8) if diagonal_passable?(@x, @y, 4, 8)
  457.       move_straight(4) if passable?(@x, @y, 4)
  458.       move_straight(8) if passable?(@x, @y, 8)
  459.     when 9
  460.       return move_diagonal(6, 8) if diagonal_passable?(@x, @y, 6, 8)
  461.       move_straight(6) if passable?(@x, @y, 6)
  462.       move_straight(8) if passable?(@x, @y, 8)
  463.     end
  464.   end
  465. end


然后这脚本用的鼠标系统是咱自己习惯用的自订版本
用其他的鼠标脚本就自己改判断的部分吧(不负责的闪人~~~
(其实只是把一般鼠标用的Mouse模组整个丢进Input里)
(基本上跟優化版的鼠標系統+全鍵盤差不多)
鼠标系统就丟在範例裡了

附件大小限制的关系
System文件夹自己拷一份
MouseMove.rar (347.62 KB, 下载次数: 715)

Lv1.梦旅人

哆啦菌

梦石
0
星屑
46
在线时间
795 小时
注册时间
2010-7-24
帖子
3800
2
发表于 2012-8-15 22:04:54 | 只看该作者
能再解释下用法么。。。另外是不是沉影不器?
随便看看
回复 支持 反对

使用道具 举报

Lv3.寻梦者

梦石
0
星屑
1210
在线时间
423 小时
注册时间
2010-12-26
帖子
337
3
发表于 2012-8-16 18:13:52 | 只看该作者
报错,内存不能为什么什么的
摘自《暗悲传》
某人
天啊!我无骂无打怎么这么多的狗,每天都要来咬我呢?......天理何在
某人
在路上看到了许多行人说道我眼前怎么全是无肺黑心肝在行走呢?
某人
有时被整的实在是受不了,很想杀狗,看看他们的心脏是黑的吗?
某人
我很喜欢黑夜与下雨,或许我只能在虚拟世界能过上一般人的生活......
某人
无论别人无良心骂我,诅咒死,刻意整蛊......希望能坚持活着!要永远记住那些人的奸诈嘴脸!
某人
又有谁能出来主持公道呢?谁能理解你,谁能站出来说句话.....他是无辜又悲苦......这真是无聊的故事吗?
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册会员

本版积分规则

拿上你的纸笔,建造一个属于你的梦想世界,加入吧。
 注册会员
找回密码

站长信箱:[email protected]|手机版|小黑屋|无图版|Project1游戏制作

GMT+8, 2024-11-15 18:53

Powered by Discuz! X3.1

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表