=begin
■ 移動ルートの拡張 for VX Ace (ver 0.0.0.2)
by 半生
[url]http://www.tktkgame.com/[/url]
● 内容
「プレイヤーに近づく」の座標指定・イベント指定バージョンのような
ものを追加します。
● 使用方法
移動ルートの指定でスクリプトを選択し以下のメソッドを指定します。
● メソッド
・ 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