赞 | 451 |
VIP | 56 |
好人卡 | 75 |
积分 | 423 |
经验 | 124650 |
最后登录 | 2024-11-12 |
在线时间 | 7597 小时 |
Lv5.捕梦者 (管理员) 老黄鸡
- 梦石
- 0
- 星屑
- 42322
- 在线时间
- 7597 小时
- 注册时间
- 2009-7-6
- 帖子
- 13505
|
这有个现成的脚本,我给你改了改可以让事件寻路
但是把返回的路径转成移动指令还得另外有人帮你写
很简单的事情。(现在有点事- #==================================================================#
- # AStar Core v1.01 by 禾西 on 2012.01.02
- #------------------------------------------------------------------#
- # (此算法基于 4 方向)
- # public methods
- # * new(Game_Map map)
- # 生成關聯地圖的 A* 實例
- # * set_origin(int ox, int oy)
- # 設置起始點(超過地圖范圍會引起 Runtime Error )
- # * set_target(int tx, int ty)
- # 設置終止點(超過地圖范圍會引起 Runtime Error )
- # * Array do_search(bool print_rst = false)
- # 進行尋路,返回包含移動信息的數組
- #
- # private methods
- # * int _f(x, y)
- # f 值算法
- # * print_data
- # 數據打印算法(此方法僅在 do_search(true) 時被使用)
- #==================================================================#
- #
- # 修改:Fux2
- # 可以使$game_player之外的事件寻路
- #
- #調用方法
- # ac = $game_map.events[self.event_id]
- # astr = AStar.new($game_map,ac)
- # astr.set_target(0, 0)
- # path = astr.do_search
- #
- # 把第一行换成ac = nil就是玩家寻路
- #
- #==================================================================#
- class AStar
- Point = Struct.new(:x, :y)
- public
- # ============================================================== #
- # 初始化數據
- # ============================================================== #
- def initialize(map,act=nil)
- [url=home.php?mod=space&uid=250514]@ACT[/url] = act ? act : $game_player
- @map_width = map.width
- @map_height = map.height
- @g_data = Table.new(@map_width, @map_height)
- @f_data = Table.new(@map_width, @map_height)
- @p_data = Table.new(@map_width, @map_height)
- @ox,@oy = @act.x,@act.y
- @tx = 0;@ty = 0
- @openList = []
- @g = 0
- @search_done = false
- end
- #~ # ============================================================== #
- #~ # 設置 起始點
- #~ # ============================================================== #
- #~ def set_origin(ox, oy)
- #~ @ox = ox;@oy = oy
- #~ if is_Overmap(ox, oy)
- #~ raise RuntimeError, "Origin location is overmap!"
- #~ end
- #~ end
- # ============================================================== #
- # 設置 目標點
- # ============================================================== #
- def set_target(tx, ty)
- @tx = tx;@ty = ty
- if is_Overmap(tx, ty)
- raise RuntimeError, "Target location is overmap!"
- end
- end
- # ============================================================== #
- # 開始尋路
- # ============================================================== #
- # 主邏輯
- def do_search(print_rst = false)
- x = @ox;y = @oy
- @g_data[x, y] = 2;@f_data[x, y] = 1
- @openList << [x, y]
- t0 = Time.now
- t = 0
- begin
- t += 1
- point = @openList.shift
- return [] if point == nil
- check_4dir(point[0], point[1]) # ->檢查 4 方向
- end until @search_done
- if @g_data[@tx,@ty] == 1
- @tx = point[0];@ty = point[1];
- end
- t1 = Time.now
- make_path # ->生成路徑
- if print_rst
- print "#{t1 - t0}, #{t}\n"
- print_data # ->打印數據
- end
- return @path
- end
-
- private
- # ============================================================== #
- # 檢查 4 方向
- def check_4dir(x, y)
- @g = @g_data[x, y] + 1
- mark_point(x, y - 1, 8) # ->檢查單點
- mark_point(x, y + 1, 2) # ->檢查單點
- mark_point(x - 1, y, 4) # ->檢查單點
- mark_point(x + 1, y, 6) # ->檢查單點
- end
- # ============================================================== #
- # 檢查單點
- def mark_point(x, y, dir)
- if is_Overmap(x, y) # ->檢查地圖是否超界
- return
- end
- if @g_data[x, y] > 1
- return
- end
- if check_passibility(x, y, dir) # ->檢查通行度
- f = _f(x, y)
- @g_data[x, y] = @g
- @f_data[x, y] = f
- point = @openList[0]
- if point.nil?
- @openList.push [x, y]
- elsif (f <= @f_data[point[0], point[1]])
- @openList.unshift [x, y]
- else
- @openList.push [x, y]
- end
- else
- @g_data[x, y] = 1
- @f_data[x, y] = _f(x, y)
- end
- if x == @tx && y == @ty
- @search_done = true
- end
- end
- # ============================================================== #
- # 生成路徑
- def make_path
- x = @tx;y = @ty
- @path = []
- while !(x == @ox && y == @oy) #TODO:有過多障礙時死轉……
- @g = @g_data[x, y]
- @best_f = 0
- dir = 0
- dir = make_step(x, y - 1, 2)||dir # ->生成單步
- dir = make_step(x, y + 1, 8)||dir # ->生成單步
- dir = make_step(x - 1, y, 6)||dir # ->生成單步
- dir = make_step(x + 1, y, 4)||dir # ->生成單步
- @path.unshift(dir)
- case dir
- when 2 then y -= 1;
- when 8 then y += 1;
- when 6 then x -= 1;
- when 4 then x += 1;
- end
- @p_data[x, y] = 1
- end
- end
- # ============================================================== #
- # 生成單步
- def make_step(x, y, dir)
- if @g_data[x, y].nil? || @p_data[x, y] == 1
- return nil
- end
- if (@g - @g_data[x, y]) == 1 || @g == 1
- f = @f_data[x, y]
- if f > 0 && (@best_f == 0 || f < @best_f)
- @best_f = f
- return dir
- end
- end
- return nil
- end
- # ============================================================== #
- # 檢查地圖通行度
- def check_passibility(x, y, dir)
- case dir
- when 2 then y -= 1;
- when 8 then y += 1;
- when 4 then x += 1;
- when 6 then x -= 1;
- end
- return @act.passable?(x, y, dir)
- end
- # ============================================================== #
- # 檢查地圖是否超界
- def is_Overmap(x, y)
- return (x|y|(@map_width - x - 1)|(@map_height - y - 1)) < 0
- end
- # ============================================================== #
- # f 值算法
- def _f(x, y)
- return ((x - @tx).abs + (y - @ty).abs) + @g
- end
- # ============================================================== #
- # 打印數據
- def print_data
- strf = ""
- strg = ""
- (0...@f_data.ysize).each do |y|
- (0...@f_data.xsize).each do |x|
- if @f_data[x, y] == 0
- strf += " "
- else
- strf += sprintf("%02d", @f_data[x, y])
- end
- strf += ","
- if @g_data[x, y] < 2
- strg += sprintf("%02d", @g_data[x, y])#" "
- else
- strg += sprintf("%02d", @g_data[x, y])
- end
- strg += ","
- end
- strf += "\n"
- strg += "\n"
- end
- print "f:\n"
- print strf + "\n"
- print "g:\n"
- print strg + "\n"
- strp = ""
- (0...@p_data.ysize).each do |y|
- (0...@p_data.xsize).each do |x|
- if @p_data[x, y] == 0
- strp += " "
- else
- strp += sprintf("%02d", @p_data[x, y])
- end
- strp += ","
- end
- strp += "\n"
- end
-
- print "p:\n"
- print strp
- print @path
- end
- end
复制代码 |
|