补充鼠标系统(同鼠标系统一起使用)

本文介绍了一种完整的八方向寻路算法实现方案,适用于游戏和机器人导航等场景。该算法详细展示了如何通过A*算法进行路径规划,并针对不同方向的移动进行了特别优化。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

#==============================================================================
# ■ Find_Path
#------------------------------------------------------------------------------
#  寻路算法--完整鼠标系统(八方向)专用版
#   By whbm
#==============================================================================
class Find_Path
#--------------------------------------------------------------------------
def initialize  #初始化
 @open_list = []
 @close_lise = []
 @path = []
end  #结束初始化
#--------------------------------------------------------------------------
def fp_passable?(x, y, d, tr_x = -2, tr_y = -2)  #开始判定通行
 return false if (tr_x == @unable_xa or
                 tr_x == @unable_xb or
                 tr_y == @unable_ya or
                 tr_y == @unable_yb)
 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 * 10
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 get_direction(self_x, self_y, trg_x, trg_y)
  if trg_x > self_x
    if trg_y - self_y > - 0.4 * ( trg_x - self_x ) and
      trg_y - self_y < 0.4 * ( trg_x - self_x )
      return 6
    end
    if trg_y - self_y > 0.4 * ( trg_x - self_x ) and
      trg_y - self_y < 2.4 * ( trg_x - self_x )
      return 3
    end
    if trg_y - self_y < - 0.4 * ( trg_x - self_x ) and
      trg_y - self_y > - 2.4 * ( trg_x - self_x )
      return 9
    end
    if trg_y - self_y > 2.4 * ( trg_x - self_x )
      return 2
    end
    if trg_y - self_y < - 2.4 * ( trg_x - self_x )
      return 8
    end
  end
  if trg_x < self_x
    if trg_y - self_y > - 0.4 * ( self_x - trg_x ) and
      trg_y - self_y < 0.4 * ( self_x - trg_x )
      return 4
    end
    if trg_y - self_y > 0.4 * ( self_x - trg_x ) and
      trg_y - self_y < 2.4 * ( self_x - trg_x )
      return 1
    end
    if trg_y - self_y < - 0.4 * ( self_x - trg_x ) and
      trg_y - self_y > - 2.4 * ( self_x - trg_x )
      return 7
    end
    if trg_y - self_y > 2.4 * ( self_x - trg_x )
      return 2
    end
    if trg_y - self_y < - 2.4 * ( self_x - trg_x )
      return 8
    end
  end
end
#--------------------------------------------------------------------------
def get_d_x_y(x, y, d)
  d_x = x + ((d == 9 or d == 6 or d == 3) ? 1 : ((d == 7 or d == 4 or d == 1) ? -1 : 0))
  d_y = y + ((d == 1 or d == 2 or d == 3) ? 1 : ((d == 7 or d == 8 or d == 9) ? -1 : 0))
  return d_x, d_y
end
#--------------------------------------------------------------------------
def find_short_path_other(self_x, self_y, trg_x, trg_y,
                          real_self_x, real_self_y, real_trg_x, real_trg_y)
  @self_x = self_x
  @self_y = self_y
  @now_x = self_x
  @now_y = self_y
  @trg_x = trg_x
  @trg_y = trg_y
  @path = []
  direction = get_direction(real_self_x, real_self_y, real_trg_x, real_trg_y)
  @now_trg_x, @now_trg_y = get_d_x_y(@self_x, @self_y, direction)
  while fp_passable?(@now_x, @now_y, direction)
    @path.push direction
    @now_x = @now_trg_x
    @now_y = @now_trg_y
    @now_trg_x, @now_trg_y = get_d_x_y(@now_x, @now_y, direction)
  end
  return @path
end
#--------------------------------------------------------------------------
def find_short_path(self_x, self_y, trg_x, trg_y,
                    real_self_x, real_self_y, real_trg_x, real_trg_y)  #开始搜索路径
 
 return find_short_path_other(self_x, self_y, trg_x, trg_y,
                              real_self_x, real_self_y, real_trg_x, real_trg_y) if not
                  (fp_passable?(trg_x, trg_y + 1, 8) or
                   fp_passable?(trg_x + 1, trg_y, 4) or
                   fp_passable?(trg_x - 1, trg_y, 6) or
                   fp_passable?(trg_x, trg_y - 1, 2)) and @goal_type != 1
                  
                  
  #根据屏幕限定搜索面积..加速
 @unable_xa = $game_map.display_x / 128 - 1
 @unable_ya = $game_map.display_y / 128 - 1
 @unable_xb = $game_map.display_x / 128 + 20
 @unable_yb = $game_map.display_y / 128 + 20
 
 
 @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 #将当前点加入关闭列表
 #开始搜索
 begin
 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
rescue Hangup
  retry
 end
 return @path
end  #结束搜索路径
#--------------------------------------------------------------------------
def find_player_short_path(trg_x, trg_y,
                           real_trg_x, real_trg_y)  #寻找角色的最短路径
 self_x = $game_player.x
 self_y = $game_player.y
 real_self_x = $game_player.screen_x
 real_self_y = $game_player.screen_y
 @goal_type, event = $game_map.check_event_custom_exist(real_trg_x, real_trg_y)
 if @goal_type == 1
   trg_x = event.x
   trg_y = event.y
 end
 return find_short_path(self_x, self_y, trg_x, trg_y,
                        real_self_x, real_self_y, real_trg_x, real_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, x, y)
       # 如果不在开启列表中、且不在关闭列表中、且通行则添加它到新八周节点
       @open_list.push new_point(x, y, 10 - d)
       #如果将目标点添加到了开启列表中就返回true
       return true if x == @trg_x and y == @trg_y
       return true if @goal_type == 1 and [1, 0, -1].include?(x - @trg_x) and [1, 0, -1].include?(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
资源下载链接为: https://pan.quark.cn/s/9648a1f24758 这个HTML文件是一个专门设计的网页,适合在告白或纪念日这样的特殊时刻送给女朋友,给她带来惊喜。它通过HTML技术,将普通文字转化为富有情感和创意的表达方式,让数字媒体也能传递深情。HTML(HyperText Markup Language)是构建网页的基础语言,通过标签描述网页结构和内容,让浏览器正确展示页面。在这个特效网页中,开发者可能使用了HTML5的新特性,比如音频、视频、Canvas画布或WebGL图形,来提升视觉效果和交互体验。 原本这个文件可能是基于ASP.NET技术构建的,其扩展名是“.aspx”。ASP.NET是微软开发的一个服务器端Web应用程序框架,支持多种编程语言(如C#或VB.NET)来编写动态网页。但为了在本地直接运行,不依赖服务器,开发者将其转换为纯静态的HTML格式,只需浏览器即可打开查看。 在使用这个HTML特效页时,建议使用Internet Explorer(IE)浏览器,因为一些老的或特定的网页特效可能只在IE上表现正常,尤其是那些依赖ActiveX控件或IE特有功能的页面。不过,由于IE逐渐被淘汰,现代网页可能不再对其进行优化,因此在其他现代浏览器上运行可能会出现问题。 压缩包内的文件“yangyisen0713-7561403-biaobai(html版本)_1598430618”是经过压缩的HTML文件,可能包含图片、CSS样式表和JavaScript脚本等资源。用户需要先解压,然后在浏览器中打开HTML文件,就能看到预设的告白或纪念日特效。 这个项目展示了HTML作为动态和互动内容载体的强大能力,也提醒我们,尽管技术在进步,但有时复古的方式(如使用IE浏览器)仍能唤起怀旧之情。在准备类似的个性化礼物时,掌握基本的HTML和网页制作技巧非常
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值