=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