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

Project1

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

[已经解决] 想将自动移动脚本用成自动接近角色

[复制链接]

Lv1.梦旅人

梦石
0
星屑
710
在线时间
12 小时
注册时间
2013-11-21
帖子
4
跳转到指定楼层
1
发表于 2013-12-12 10:29:07 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式

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

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

x
本帖最后由 c3349354 于 2013-12-12 10:37 编辑

因为系统自带的“接近”移动方式不能绕开障碍物
本人想将下面两个脚本(OCTSJimmy的自动移动和whbm的四方向寻路)的自动寻路功能用在NPC靠近角色方面
但是在使用的时候在NPC的自定义路线里填上脚本tomove($game_player.x, $game_player.y)后
NPC不移动,但是游戏并未卡住
请问一下要怎么做才能达到我的目的呢?



自动移动

#============================================================================
# 本脚本来自www.66RPG.com,使用和转载请保留此信息
#============================================================================
#----------------------------------------------------------------------------
#            自动移动 By OCTSJimmy 感谢 whbm 提供帮助
=begin
  该脚本必须有 whbm 的 寻路算法:四方向 的支持
  使用该脚本到是很简单
  在需要开始自动移动的事件中填入
   
  设置移动路线:(目标人物)
              脚本 tomove(目标坐标x, 目标坐标y)
               
  如此即可
   
  例如要使 角色 开始 自动移动 到地图的 (0,0) 位置那么就可以这样写
  ◆设置移动路线: 角色
   :            : ◇脚本 : tomove(0, 0)
  ◆
  其余的同样如此设置
   
  需要注意的是:
      如果目标坐标所处的图块为不可通行且穿透没有打开的话那么将不会有任何动作
  甚至连路线数组也不会生成。
=end
#----------------------------------------------------------------------------
class Interpreter
#--------------------------------------------------------------------------
# ● 获取角色
#     parameter : 能力值
#--------------------------------------------------------------------------
def get_character_n(parameter)
   # 能力值分支
   #★★★★★★★★增加★★★★★★★★★★
   $mubiao = parameter
   $event_id_all = @event_id
   #★★★★★★★★增加★★★★★★★★★★
   case parameter
   when -1  # 角色
     return $game_player
   when 0  # 本事件
     events = $game_map.events
     return events == nil ? nil : events[@event_id]
   else  # 特定的事件
     events = $game_map.events
     return events == nil ? nil : events[parameter]
   end
end
alias get_character get_character_n
end
class Game_Character
#---------------------------新增-------------------------------------------
# ● 寻路移动
#---------------------------新增-------------------------------------------
def tomove(x, y)
   #当操作目标为 角色 时
   if $mubiao == -1
     @tmp_x = x
     @tmp_y = y
     #调用寻路算法,开始计算路线
     $find_path = Find_Path.new
     @path = $find_path.find_player_short_path(@tmp_x,@tmp_y)
      
   #当操作目标为 本事件 时
   elsif $mubiao == 0
     @tmp_x = x
     @tmp_y = y
     @tmp_id_x = $game_map.events[$event_id_all].x
     @tmp_id_y = $game_map.events[$event_id_all].y
     #调用寻路算法,开始计算路线
     $find_path = Find_Path.new
     @path = $find_path.find_short_path(@tmp_id_x, @tmp_id_y, @tmp_x, @tmp_y)
   #当操作目标为 其他事件 时
   else
     @tmp_x = x
     @tmp_y = y
     @tmp_id_x = $game_map.events[$mubiao].x
     @tmp_id_y = $game_map.events[$mubiao].y
     #调用寻路算法,开始计算路线
     $find_path = Find_Path.new
     @path = $find_path.find_short_path(@tmp_id_x, @tmp_id_y, @tmp_x, @tmp_y)
   end
   #开始自动移动,参照本类的 update方法
   @go_path = true
   #自动移动 处理位置初始化
   @path_id = 0
end
#--------------------------------------------------------------------------
# ● 刷新画面
#--------------------------------------------------------------------------
def update_n
# 跳跃中、移动中、停止中的分支
   if jumping?
     update_jump
   elsif moving?
     update_move
   else
     update_stop
   end
   # 动画计数超过最大值的情况下
   # ※最大值等于基本值减去移动速度 * 1 的值
   if @anime_count > 18 - @move_speed * 2
     # 停止动画为 OFF 并且在停止中的情况下
     if not @step_anime and @stop_count > 0
       # 还原为原来的图形
       @pattern = @original_pattern
     # 停止动画为 ON 并且在移动中的情况下
     else
       # 更新图形
       @pattern = (@pattern + 1) % 4
     end
     # 清除动画计数
     @anime_count = 0
   end
   # 等待中的情况下
   if @wait_count > 0
     # 减少等待计数
     @wait_count -= 1
     return
   end
   # 强制移动路线的场合
   if @move_route_forcing
     # 自定义移动
     move_type_custom
     return
   end
   # 事件执行待机中并且为锁定状态的情况下
   if @starting or lock?
     # 不做规则移动
     return
   end
   # 如果停止计数超过了一定的值(由移动频度算出)
   if @stop_count > (40 - @move_frequency * 2) * (6 - @move_frequency)
     # 移动类型分支
     case @move_type
     when 1  # 随机
       move_type_random
     when 2  # 接近
       move_type_toward_player
     when 3  # 自定义
       move_type_custom
     end
   end
   #---------------------------新增-------------------------------------------
   #当 自动移动 标记为真 以及 不在移动时
   if @go_path and !moving?
     #依据 自动移动 处理位置 判断下一步该往哪儿走
     case @path[@path_id]
     when 2
       move_down
     when 4
       move_left
     when 6
       move_right
     when 8
       move_up
     end
     #自动移动 处理位置 递增
     @path_id += 1
     #假如 自动移动 处理位置 到达 路线数组的末尾
     if @path_id == @path.size
       #使得 自动移动 标记重置
       @go_path = false
     end
   end
end
alias update update_n
end
#============================================================================
# 本脚本来自www.66RPG.com,使用和转载请保留此信息
#============================================================================


寻路算法


#==============================================================================
# ■ Find_Path
#------------------------------------------------------------------------------
#  寻路算法
#   By whbm
#==============================================================================
class Find_Path
#--------------------------------------------------------------------------
def initialize  #初始化
@open_list = []
@close_lise = []
end  #结束初始化
#--------------------------------------------------------------------------
def fp_passable?(x, y, d)  #开始判定通行
if [2, 4, 6, 8].include?(d)
   if $game_player.passable?(x, y, d)
     return true
   else
     return false
   end
else
   case d
   when 1
     if ($game_player.passable?(x, y, 4) and
       $game_player.passable?(x - 1, y, 2)) or
        ($game_player.passable?(x, y, 2) and
       $game_player.passable?(x, y + 1, 4))
       return true
     else
       return false
     end
   when 3
     if ($game_player.passable?(x, y, 6) and
       $game_player.passable?(x + 1, y, 2)) or
        ($game_player.passable?(x, y, 2) and
       $game_player.passable?(x, y + 1, 6))
       return true
     else
       return false
     end
   when 7
     if ($game_player.passable?(x, y, 4) and
       $game_player.passable?(x - 1, y, 8)) or
        ($game_player.passable?(x, y, 8) and
       $game_player.passable?(x, y - 1, 4))
       return true
     else
       return false
     end
   when 9
     if ($game_player.passable?(x, y, 6) and
       $game_player.passable?(x + 1, y, 8)) or
        ($game_player.passable?(x, y, 8) and
       $game_player.passable?(x, y - 1, 6))
       return true
     else
       return false
     end
   end
end
end  #结束判定通行
#--------------------------------------------------------------------------
def get_g(now_point)  #开始计算G值
d = now_point[2]
return 0 if d == 5
father_point = get_father_point(now_point)
g = father_point[3] + ((d == 1 or d == 3 or d == 7 or d == 9) ? 14 : 10)
return g
end  #结束计算G值
#--------------------------------------------------------------------------
def get_h(now_point)  #开始计算H值
now_x = now_point[0]
now_y = now_point[1]
#print @trg_x,now_x,@trg_y,now_y
h = (@trg_x - now_x).abs + (@trg_y - now_y).abs
return h
end  #结束计算H值
#--------------------------------------------------------------------------
def get_f(now_point)  #开始计算F值
f = now_point[3] + now_point[4]
return f
end  #结束计算F值
#--------------------------------------------------------------------------
def get_point(x, y) #取已知坐标点
if @open_list.size != 0
   @open_list.each do |point|
     if point[0] == x and point[1] == y
       return point
       break
     end
   end
end
if @close_list.size != 0
   @close_list.each do |point|
     if point[0] == x and point[1] == y
       return point
       break
     end
   end
end
end  #结束取已知坐标点
#--------------------------------------------------------------------------
def get_father_point(now_point)  #取已知点的父节点
d = now_point[2]
return now_point if d == 5
x = now_point[0] + ((d == 9 or d == 6 or d == 3) ? 1 : ((d == 7 or d == 4 or d == 1) ? -1 : 0))
y = now_point[1] + ((d == 1 or d == 2 or d == 3) ? 1 : ((d == 7 or d == 8 or d == 9) ? -1 : 0))
return get_point(x, y)
end  #结束取已知点的父节点
#--------------------------------------------------------------------------
def new_point(x, y, d)  #开始建立新节点
#print x,y,d
point = [x, y, d]
point.push get_g(point)
point.push get_h(point)
point.push get_f(point)
return point
end  #结束建立新节点
#--------------------------------------------------------------------------
def find_short_path(self_x, self_y, trg_x, trg_y)  #开始搜索路径
return [] if not (fp_passable?(trg_x, trg_y, 8) or
                   fp_passable?(trg_x, trg_y, 4) or
                   fp_passable?(trg_x, trg_y, 6) or
                   fp_passable?(trg_x, trg_y, 2))
@self_x = self_x
@self_y = self_y
@now_x = self_x
@now_y = self_y
@trg_x = trg_x
@trg_y = trg_y
@open_list = []
@close_list = []
#准备搜索
#print @self_x,@self_y
@now_point = new_point(@self_x, @self_y, 5) #令起始点为当前点
@open_list.push @now_point #将当前点加入关闭列表
#开始搜索
loop do
   check_trg = check_around_point(@now_point)
   if check_trg == true
     @path = get_path
     break
   end
   @now_point = get_lowest_f_point
   if @now_point == [] or @now_point == nil
     @path = []
     break
   end
end
return @path
end  #结束搜索路径
#--------------------------------------------------------------------------
def find_player_short_path(trg_x, trg_y)  #寻找角色的最短路径
self_x = $game_player.x
self_y = $game_player.y
return find_short_path(self_x, self_y, trg_x, trg_y)
end  #结束角色的寻找路径
#--------------------------------------------------------------------------
def get_path  #取得最终的路径
path = []
now_point = @open_list[@open_list.size - 1]
path.push(10 - now_point[2])
last_point = now_point
loop do
   now_point = get_father_point(now_point)
   break if now_point[2] == 5
   path.push(10 - now_point[2])
end
return path.reverse
end  #结束取得最终的路径
#--------------------------------------------------------------------------
def get_lowest_f_point  #开始取得最低F值的点
if @open_list == []
   return []
end
last_lowest_f_point = @open_list[0]
@open_list.each do |point|
   last_lowest_f_point = point if point[5] < last_lowest_f_point[5]
end
return last_lowest_f_point
end  #结束取得最低F值点
#--------------------------------------------------------------------------
def check_around_point(point)  #开始检查已知点的八方节点
for d in [1, 2, 3, 4, 6, 7, 8, 9]
   x = point[0] + ((d == 9 or d == 6 or d == 3) ? 1 : ((d == 7 or d == 4 or d == 1) ? -1 : 0))
   y = point[1] + ((d == 1 or d == 2 or d == 3) ? 1 : ((d == 7 or d == 8 or d == 9) ? -1 : 0))
   if in_close_list?(x, y) #在关闭列表中
     next
   elsif in_open_list?(x, y) #在开启列表中
     get_new_g_point = new_point(x, y, 10 - d)
     get_last_g_point = get_point(x, y)
     if get_new_g_point[3] >= get_last_g_point[3]
       next
     else
       #如果改变父节点是新G值更小则确定改变
       @open_list[@open_list.index(get_last_g_point)] = get_new_g_point
     end
   else
     if fp_passable?(point[0], point[1], d)
       # 如果不在开启列表中、且不在关闭列表中、且通行则添加它到新八周节点
       @open_list.push new_point(x, y, 10 - d)
       #如果将目标点添加到了开启列表中就返回true
       return true if x == @trg_x and y == @trg_y
     end
   end
end
#此刻没有找到目标点并将当前点加入关闭列表并在开启列表中删除
@close_list.push point
@open_list.delete(point)
#此刻没找到目标点并返回false
return false
end  #结束计算已知点的八方节点
#--------------------------------------------------------------------------
def in_open_list?(x, y)  #开始检查谋点是否在开启列表中
@open_list.each do |point|
   return true if point[0] == x and point[1] == y
end
return false
end  #结束检查谋点是否在开启列表中
#--------------------------------------------------------------------------
def in_close_list?(x, y)  #开始检查谋点是否在关闭列表中
@close_list.each do |point|
   return true if point[0] == x and point[1] == y
end
return false
end  #结束检查谋点是否在关闭列表中
#--------------------------------------------------------------------------
end

Lv1.梦旅人

梦石
0
星屑
710
在线时间
12 小时
注册时间
2013-11-21
帖子
4
2
 楼主| 发表于 2013-12-12 10:36:53 | 只看该作者
啊不好意思……问题突然解决了
回复 支持 反对

使用道具 举报

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

本版积分规则

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

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

GMT+8, 2024-12-1 01:37

Powered by Discuz! X3.1

© 2001-2013 Comsenz Inc.

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