查看: 4401|回复: 1

[已经解决] [已解決]关于AStar寻路扩展.rb的用法

[复制链接]
头像被屏蔽
梦石
0
星屑
5706
在线时间
922 小时
注册时间
2013-8-29
回帖
1401
发表于 2020-2-16 01:14:56 | 显示全部楼层 |阅读模式
提示: 作者被禁止或删除 内容自动屏蔽

老鹰

梦石
40
星屑
37812
在线时间
7091 小时
注册时间
2012-5-26
回帖
3297

极短24评委极短23参与极短22参与极短21评委老司机慢点开短篇十吟唱者组别冠军开拓者剧作品鉴家

发表于 2020-2-16 10:52:12 | 显示全部楼层
本帖最后由 百里_飞柳 于 2020-2-16 10:55 编辑

这个是用于做追逐的使用方式,也就是在每一次移动时都必定为了移动到目的地

如果你想做事件移动到指定地点之后,继续执行其他事件指令
请使用 循环-等待1帧(为了同时能更新画面)-事件移动路线AStar(不重复动作)-如果事件x==目的地x并且事件y==目的地y 就跳出循环-结束循环,之后继续执行其他指令

或者使用这个脚本,利用 事件移动路线中的脚本 move2pos(x, y),并且等待移动结束,来将事件移动到指定位置并结束移动
[pre lang="ruby"]=begin
■ 移動ルートの拡張 for VX Ace (ver 0.0.0.2)
  by 半生
  http://www.tktkgame.com/

● 内容
 「プレイヤーに近づく」の座標指定・イベント指定バージョンのような
 ものを追加します。

● 使用方法
  移動ルートの指定でスクリプトを選択し以下のメソッドを指定します。

● メソッド
・ move2pos(tx, ty [, option])
     指定座標に一歩近づく
     tx, ty : 目標のマップ座標
     option : ハッシュでオプションを指定(省略可)
       :random_rate => 数字を指定するとその%の確率でランダム移動が入ります
       :circumvent  => trueを指定すると微妙に回り込んだりします。

・ move2pos_wait(tx, ty [, option])
     目的地にたどり着くまで指定座標に近づくを繰り返します。
     「移動できない場合は無視」を無視します。
     tx, ty : 目標のマップ座標
     option : move2posと同じもの+[:distance]オプション
       :distance => 対象と接触したとみなす距離(デフォルト:0)

・ move2event(event_id [, option])
     指定イベントに一歩近づく
     event_id : 目標のイベントID
     option : move2posと同じ

・ move2event_wait(event_id [, option])
     指定イベントに接触するまで近づくを繰り返す
     event_id : 目標のマップイベントID
     option : move2posと同じもの+[:distance]オプション
       :distance => 対象と接触したとみなす距離(デフォルト:1)

・ turn_toward_pos(tx, ty)
     指定座標の方向を向く
     tx, ty : 目標のマップ座標

・ turn_toward_event(event_id)
     指定イベントの方向を向く
     event_id : 目標のイベントID


  ■ 更新履歴
    ver 0.0.0.2 (2013/12/29)
     回り込み処理の修正
    ver 0.0.0.1 (2013/12/29)
     公開

=end

module TkTkGame
end

module TkTkGame::MovePlus
  module Extend_GameCharacter
    #--------------------------------------------------------------------------
    # ● 指定位置からの X 距離計算
    #--------------------------------------------------------------------------
    def distance_x_from_target(tx)
      sx = @x - tx
      if $game_map.loop_horizontal?         # 横にループしているとき
        if sx.abs > $game_map.width / 2     # 絶対値がマップの半分より大きい?
          if sx > 0
            sx -= $game_map.width           # マップの幅を引く
          else
            sx += $game_map.width           # マップの幅を足す
          end
        end
      end
      return sx
    end
   
    #--------------------------------------------------------------------------
    # ● 指定位置からの Y 距離計算
    #--------------------------------------------------------------------------
    def distance_y_from_target(ty)
      sy = @y - ty
      if $game_map.loop_vertical?           # 縦にループしているとき
        if sy.abs > $game_map.height / 2    # 絶対値がマップの半分より大きい?
          if sy > 0
            sy -= $game_map.height          # マップの高さを引く
          else
            sy += $game_map.height          # マップの高さを足す
          end
        end
      end
      return sy
    end

    #--------------------------------------------------------------------------
    # ● 指定位置からの 歩数計算
    #--------------------------------------------------------------------------
    def steps_from_pos(tx, ty)
      sx = @x - tx
      sy = @y - ty
      if $game_map.loop_horizontal?         # 横にループしているとき
        if sx.abs > $game_map.width / 2     # 絶対値がマップの半分より大きい?
          if sx > 0
            sx -= $game_map.width           # マップの幅を引く
          else
            sx += $game_map.width           # マップの幅を足す
          end
        end
      end
      if $game_map.loop_vertical?           # 縦にループしているとき
        if sy.abs > $game_map.height / 2    # 絶対値がマップの半分より大きい?
          if sy > 0
            sy -= $game_map.height          # マップの高さを引く
          else
            sy += $game_map.height          # マップの高さを足す
          end
        end
      end
      return sx.abs + sy.abs
    end
   
    #--------------------------------------------------------------------------
    # ● 指定座標の方を向く
    #--------------------------------------------------------------------------
    def turn_toward_pos(tx, ty)
      sx = distance_x_from_target(tx)
      sy = distance_y_from_target(ty)
      if sx.abs > sy.abs                    # 横の距離のほうが長い
        sx > 0 ? turn_left : turn_right
      elsif sx.abs < sy.abs                 # 縦の距離のほうが長い
        sy > 0 ? turn_up : turn_down
      end
    end
   
    #--------------------------------------------------------------------------
    # ● 指定イベントの方を向く
    #--------------------------------------------------------------------------
    def turn_toward_event(event_id)
      event = $game_map.events[event_id]
      return unless event.is_a?(Game_Event)
      turn_toward_pos(event.x, event.y)
    end
   
    #--------------------------------------------------------------------------
    # ● 指定位置に近づく
    #--------------------------------------------------------------------------
    # tx,ty: 目標地点の座標
    # oprion: {:random_rate => 5, :circumvent => true}のようにハッシュで指定
    #   [:random_rate] : ランダム移動する確率[%]
    #   [:circumvent] : 進めないときに回り込むかどうか[true or false]
    def move2pos(tx, ty, option={})
      sx = distance_x_from_target(tx)
      sy = distance_y_from_target(ty)
      if sx != 0 or sy != 0
        # 回り込み判定
        if option.key?(:circumvent) and option[:circumvent]
          circumvent = true
        else
          circumvent = false
        end
        
        if @tkgc_reserved_move != nil
          case @tkgc_reserved_move
          when 2,4,6,8
            move_straight(@tkgc_reserved_move)
          else
            @move_succeed = false
          end
          @tkgc_reserved_move = nil
          # 移動成功時はそのまま終了
          return if @move_succeed
        end
        
        # 確率ランダム移動が指定されている場合
        if option.key?(:random_rate)
          if rand(100) < option[:random_rate].to_i
            return move_random
          end
        end
        
        # 近づく処理
        if sx.abs > sy.abs                  # 横の距離のほうが長い
          move_straight(sx > 0 ? 4 : 6)   # 左右方向を優先
          if !@move_succeed
            if sy != 0
              move_straight(sy > 0 ? 8 : 2)
            end
            if !@move_succeed and circumvent
              if sx < 0
                next_x = @x + 1
                next_move = 6
              else
                next_x = @x - 1
                next_move = 4
              end
              if rand(2) == 0
                move_straight(8) if passable?(@x, @y, 8) and passable?(@x, @y-1, next_move)
                move_straight(2) if !@move_succeed and passable?(@x, @y, 2) and passable?(@x, @y+1, next_move)
              else
                move_straight(2) if passable?(@x, @y, 2) and passable?(@x, @y+1, next_move)
                move_straight(8) if !@move_succeed and passable?(@x, @y, 8) and passable?(@x, @y-1, next_move)
              end
              if @move_succeed
                @tkgc_reserved_move = next_move
              end
            end
          end
        else                                # 縦の距離のほうが長いか等しい
          move_straight(sy > 0 ? 8 : 2)      # 上下方向を優先
          if !@move_succeed
            if sx != 0
              move_straight(sx > 0 ? 4 : 6)
            end
            if !@move_succeed and circumvent
              if sy < 0
                next_y = @y + 1
                next_move = 2
              else
                next_y = @y - 1
                next_move = 8
              end
              if rand(2) == 0
                move_straight(4) if passable?(@x ,@y, 4) and passable?(@x-1 ,@y, next_move)
                move_straight(6) if !@move_succeed and  passable?(@x ,@y, 6) and passable?(@x+1, @y, next_move)
              else
                move_straight(6) if passable?(@x ,@y, 6) and passable?(@x+1 ,@y, next_move)
                move_straight(4) if !@move_succeed and passable?(@x ,@y, 4) and passable?(@x-1, @y, next_move)
              end
              unless !@move_succeed
                @tkgc_reserved_move = next_move
              end
            end
          end
        end
      end
    end # Game_Character#move2pos

    #--------------------------------------------------------------------------
    # ● 指定位置に近づく(移動完了まで繰り返す)
    #--------------------------------------------------------------------------
    def move2pos_wait(tx, ty, option={})
      if option.key?(:distance)
        distance = option[:distance].to_i
      else
        distance = 0
      end
      move2pos(tx, ty, option)
      sx = distance_x_from_target(tx)
      sy = distance_y_from_target(ty)
      # 移動後に目的地に到着
      if steps_from_pos(tx, ty) <= distance
        @hn_reserved_mov = nil
        @move_succeed = true
      else
        if @move_route.skippable
          @move_route_index -= 1
        end
        @move_succeed = false
      end
    end
   
    #--------------------------------------------------------------------------
    # ● マップイベントに近づく
    #--------------------------------------------------------------------------
    def move2event(event_id, option={})
      event = $game_map.events[event_id]
      return unless event.is_a?(Game_Event)
      move2pos(event.x, event.y, option)
    end
   
    #--------------------------------------------------------------------------
    # ● マップイベントに近づく(移動完了まで繰り返す)
    #--------------------------------------------------------------------------
    def move2event_wait(event_id, option={})
      if option.key?(:distance)
        distance = option[:distance].to_i
      else
        distance = 1
      end
      
      event = $game_map.events[event_id]
      return unless event.is_a?(Game_Event)
      tx = event.x
      ty = event.y
      
      # 指定された距離まで近づいている場合
      if steps_from_pos(tx, ty) <= distance
        turn_toward_pos(tx, ty)
        @move_succeed = true
        @hn_reserved_mov = nil
        return
      end

      # 目標イベントに向かって移動
      move2pos(tx, ty, option)


      # 到達していない場合は繰り返す
      if @move_route.skippable
        @move_route_index -= 1
      end
      @move_succeed = false
    end
   
    # ■ 移動ルート拡張関連パラメータのリセット
    def reset_move2pos_params
      @tkgc_reserved_move = nil
    end
   
    # ■ 移動ルートの強制
    def force_move_route(move_route)
      reset_move2pos_params
      super(move_route)
    end

    # ■ 移動タイプ : カスタム
    def update_routine_move
      # 移動ルートの強制が解除されるときに移動予約も解除
      if stopping? and @move_route.list[@move_route_index] == 0 and @move_route_forcing
        reset_move2pos_params
      end
      super
    end
  end
end

class Game_Event
  include TkTkGame::MovePlus::Extend_GameCharacter
  alias :_hn_mplus__setup_page :setup_page unless method_defined?(:_hn_mplus__setup_page)
  def setup_page(*args)
    reset_move2pos_params
    _hn_mplus__setup_page(*args)
  end
end

class Game_Player
  include TkTkGame::MovePlus::Extend_GameCharacter
  # ■ 指定位置に移動
  alias :_hn_mplus__moveto :moveto unless method_defined?(:_hn_mplus__moveto)
  def moveto(x, y)
    reset_move2pos_params
    _hn_mplus__moveto(x, y)
  end
end
[/pre]

评分

参与人数 2星屑 +100 赞 +1 收起 理由
VIPArcher + 100 认可答案
chanszeman1018 + 1 认可答案

查看全部评分

回复

使用道具 举报

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

本版积分规则

Powered by Discuz! X5.0 © 2001-2026 Discuz! Team.

在本版发帖返回顶部