#============================================================================== # ★ ドット移動 ver 2.8 [2008-02-13] #------------------------------------------------------------------------------ # マップでドット移動 (マスを無視して移動) させるスクリプトです。 #------------------------------------------------------------------------------ # スクリプト : shun (Simp : http://simp.nobody.jp) #============================================================================== #============================================================================== # □ Dms #------------------------------------------------------------------------------ # Simp のスクリプト素材 [ドット移動] の設定を扱うモジュールです。定数をそれ # ぞれのクラス, モジュールから参照します。 #------------------------------------------------------------------------------ # スクリプトユーザーは、このモジュールで定義する定数を変更することにより設定 # を変更することができます。 #============================================================================== module Dms # # ◇ 8 方向移動するか # EIGHT = true # # ◇ ダッシュ # DASH_TYPE = 2 # 0..ダッシュしない, 1..押下時, 2..立ち止まるまで DASH_BUTTON = Input::C # ダッシュボタン (Input::ボタン) # ヘルプの Input の定数の項目を参照してみて下さい。 end #============================================================================== # ■ Numeric #============================================================================== class Numeric < Object #-------------------------------------------------------------------------- # ○ 任意桁の切り捨て # d : 切り捨てる桁 #-------------------------------------------------------------------------- def rounddown(d = 0) x = 10 ** -d (self * x).truncate.quo(x) end end #============================================================================== # ■ Game_Player #============================================================================== class Game_Player < Game_Character #-------------------------------------------------------------------------- # ● 公開インスタンス変数 #-------------------------------------------------------------------------- attr_writer :width # グラフィックの幅 attr_writer :height # グラフィックの高さ #-------------------------------------------------------------------------- # ● オブジェクト初期化 #-------------------------------------------------------------------------- def initialize super @real_direction = 2 end #-------------------------------------------------------------------------- # ● すり抜け判定 #-------------------------------------------------------------------------- def through # 外部としての自分に対するチェックでは true を返す # (すり抜けとしての判定は @through で直接参照される) return (@passable_checking or super) end #-------------------------------------------------------------------------- # ● 通行可能判定 # x : X 座標 # y : Y 座標 # d : 方向 (0,2,4,5,6,8) # ※ 0..全方向通行不可の場合を判定 (ジャンプ用), 5..常に true #-------------------------------------------------------------------------- alias :__orig_dms__passable? :passable? def passable?(x, y, d) @passable_checking = true result = true # 移動制限の範囲を算出 range_x = (x + 0.5 - @width.quo(2) )..(x + 0.5 + @width.quo(2)) range_y = (y + 0.5 - @height.quo(2))..(y + 0.5 + @height.quo(2)) if d == 2 or d == 8 # Y 方向 min_x, max_x = range_x.first.floor, range_x.last.ceil - 1 (min_x..max_x).each {|sx| unless __orig_dms__passable?(sx, y.truncate, d) result = false break end } elsif d == 4 or d == 6 # X 方向 min_y, max_y = range_y.first.floor, range_y.last.ceil - 1 (min_y..max_y).each {|sy| unless __orig_dms__passable?(x.truncate, sy, d) result = false break end } end @passable_checking = false return result end #-------------------------------------------------------------------------- # ● 歩数増加 #-------------------------------------------------------------------------- alias :__orig_dms__increase_steps :increase_steps def increase_steps __orig_dms__increase_steps # イベント実行中、移動ルート強制中 # デバッグモードが ON かつ CTRL キーが押されている場合のいずれでもない場合 unless $game_system.map_interpreter.running? or @move_route_forcing or ($DEBUG and Input.press?(Input::CTRL)) # エンカウント カウントダウン @encounter_count -= 1 if @encounter_count > 0 end end #-------------------------------------------------------------------------- # ● 同位置のイベント起動判定 #-------------------------------------------------------------------------- alias :__orig_dms__check_event_trigger_here :check_event_trigger_here def check_event_trigger_here(triggers) last_x, last_y = @x, @y @x, @y = @x.round, @y.round result = __orig_dms__check_event_trigger_here(triggers) @x, @y = last_x, last_y return result end #-------------------------------------------------------------------------- # ● 正面のイベント起動判定 #-------------------------------------------------------------------------- alias :__orig_dms__check_event_trigger_there :check_event_trigger_there def check_event_trigger_there(triggers) last_x, last_y = @x, @y @x, @y = @x.round, @y.round result = __orig_dms__check_event_trigger_there(triggers) @x, @y = last_x, last_y return result end #-------------------------------------------------------------------------- # ● 接触イベントの起動判定 #-------------------------------------------------------------------------- alias :__orig_dms__check_event_trigger_touch :check_event_trigger_touch def check_event_trigger_touch(x, y) __orig_dms__check_event_trigger_touch(x.round, y.round) end #-------------------------------------------------------------------------- # ● フレーム更新 #-------------------------------------------------------------------------- def update # ダッシュフラグをクリア @dash = false if Dms::DASH_TYPE == 1 # 移動中、イベント実行中、移動ルート強制中、 # メッセージウィンドウ表示中のいずれでもない場合 unless moving? or $game_system.map_interpreter.running? or @move_route_forcing or $game_temp.message_window_showing # ダッシュボタンが押されていれば、ダッシュフラグをセット @dash = true if Input.press?(Dms::DASH_BUTTON) and Dms::DASH_TYPE != 0 # 方向ボタンが押されていれば、その方向へプレイヤーを移動 dir = (Dms::EIGHT ? Input.dir8 : Input.dir4) case dir when 1 ; move_lower_left when 2 ; move_down when 3 ; move_lower_right when 4 ; move_left when 6 ; move_right when 7 ; move_upper_left when 8 ; move_up when 9 ; move_upper_right end end # ローカル変数に座標を記憶 last_real_x, last_real_y = @real_x, @real_y super # 移動しなかった場合、ダッシュフラグをクリア @dash = false if @real_x == last_real_x and @real_y == last_real_y # キャラクターが下に移動し、かつ画面上の位置が中央より下の場合 if @real_y > last_real_y and @real_y - $game_map.display_y > CENTER_Y # マップを下にスクロール $game_map.scroll_down(@real_y - last_real_y) end # キャラクターが左に移動し、かつ画面上の位置が中央より左の場合 if @real_x < last_real_x and @real_x - $game_map.display_x < CENTER_X # マップを左にスクロール $game_map.scroll_left(last_real_x - @real_x) end # キャラクターが右に移動し、かつ画面上の位置が中央より右の場合 if @real_x > last_real_x and @real_x - $game_map.display_x > CENTER_X # マップを右にスクロール $game_map.scroll_right(@real_x - last_real_x) end # キャラクターが上に移動し、かつ画面上の位置が中央より上の場合 if @real_y < last_real_y and @real_y - $game_map.display_y < CENTER_Y # マップを上にスクロール $game_map.scroll_up(last_real_y - @real_y) end # 移動中ではない場合 unless moving? # 同位置のイベントとの接触によるイベント起動判定 check_event_trigger_here([1,2]) # C ボタンが押された場合 if Input.trigger?(Input::C) # 同位置および正面のイベント起動判定 check_event_trigger_here([0]) check_event_trigger_there([0,1,2]) end end end #-------------------------------------------------------------------------- # ● フレーム更新 (移動) #-------------------------------------------------------------------------- def update_move # ダッシュフラグが有効なら、一時的に移動速度を上げる @move_speed += 1 if @dash super @move_speed -= 1 if @dash end #-------------------------------------------------------------------------- # ● 下に移動 # turn_enabled : その場での向き変更を許可するフラグ #-------------------------------------------------------------------------- def move_down(turn_enabled = true) # 下を向く turn_down if turn_enabled # 座標をずらす shift_coord(0, 1) end #-------------------------------------------------------------------------- # ● 左に移動 # turn_enabled : その場での向き変更を許可するフラグ #-------------------------------------------------------------------------- def move_left(turn_enabled = true) # 左を向く turn_left if turn_enabled # 座標をずらす shift_coord(-1, 0) end #-------------------------------------------------------------------------- # ● 右に移動 # turn_enabled : その場での向き変更を許可するフラグ #-------------------------------------------------------------------------- def move_right(turn_enabled = true) # 右を向く turn_right if turn_enabled # 座標をずらす shift_coord(1, 0) end #-------------------------------------------------------------------------- # ● 上に移動 # turn_enabled : その場での向き変更を許可するフラグ #-------------------------------------------------------------------------- def move_up(turn_enabled = true) # 上を向く turn_up if turn_enabled # 座標をずらす shift_coord(0, -1) end #-------------------------------------------------------------------------- # ● 左下に移動 #-------------------------------------------------------------------------- def move_lower_left # 向き固定でない場合 unless @direction_fix # 右向きだった場合は左を、上向きだった場合は下を向く @direction = (@direction == 6 ? 4 : @direction == 8 ? 2 : @direction) @real_direction = 1 end # 座標をずらす shift_coord(-1, 1) end #-------------------------------------------------------------------------- # ● 右下に移動 #-------------------------------------------------------------------------- def move_lower_right # 向き固定でない場合 unless @direction_fix # 左向きだった場合は右を、上向きだった場合は下を向く @direction = (@direction == 4 ? 6 : @direction == 8 ? 2 : @direction) @real_direction = 3 end # 座標をずらす shift_coord(1, 1) end #-------------------------------------------------------------------------- # ● 左上に移動 #-------------------------------------------------------------------------- def move_upper_left # 向き固定でない場合 unless @direction_fix # 右向きだった場合は左を、下向きだった場合は上を向く @direction = (@direction == 6 ? 4 : @direction == 2 ? 8 : @direction) @real_direction = 7 end # 座標をずらす shift_coord(-1, -1) end #-------------------------------------------------------------------------- # ● 右上に移動 #-------------------------------------------------------------------------- def move_upper_right # 向き固定でない場合 unless @direction_fix # 左向きだった場合は右を、下向きだった場合は上を向く @direction = (@direction == 4 ? 6 : @direction == 2 ? 8 : @direction) @real_direction = 9 end # 座標をずらす shift_coord(1, -1) end #-------------------------------------------------------------------------- # ● 一歩前進 #-------------------------------------------------------------------------- def move_forward # 向き固定の状態を記憶 last_direction_fix = @direction_fix # 強制的に向き固定を解除 @direction_fix = false case @real_direction when 1 ; move_lower_left when 2 ; move_down(false) when 3 ; move_lower_right when 4 ; move_left(false) when 6 ; move_right(false) when 7 ; move_upper_left when 8 ; move_up(false) when 9 ; move_upper_right end # 向き固定の状態を元に戻す @direction_fix = last_direction_fix end #-------------------------------------------------------------------------- # ● 一歩後退 #-------------------------------------------------------------------------- def move_backward # 向き固定の状態を記憶 last_direction_fix = @direction_fix # 強制的に向き固定 @direction_fix = true # 向きで分岐 case @real_direction when 1 ; move_upper_right when 2 ; move_up(false) when 3 ; move_upper_left when 4 ; move_right(false) when 6 ; move_left(false) when 7 ; move_lower_right when 8 ; move_down(false) when 9 ; move_lower_left end # 向き固定の状態を元に戻す @direction_fix = last_direction_fix end #-------------------------------------------------------------------------- # ○ 座標をずらす # x : X 方向の移動量 (論理座標) # y : Y 方向の移動量 (論理座標) #-------------------------------------------------------------------------- def shift_coord(x, y) # 移動速度からマップ座標系での移動距離に変換 speed = (@dash ? @move_speed + 1 : @move_speed) distance = (2 ** speed).quo(128).rounddown(-3) distance = 1 if @move_route_forcing and not @dot dx, dy = x * distance, y * distance # ローカル変数に座標を記憶 last_x, last_y = @x.truncate, @y.truncate # 移動制限の範囲を算出 range_x = (@x + 0.5 - @width.quo(2) )..(@x + 0.5 + @width.quo(2)) range_y = (@y + 0.5 - @height.quo(2))..(@y + 0.5 + @height.quo(2)) # 実際の移動距離を算出 if dx > 0 # 右方向 min_x, max_x = range_x.first.floor, (range_x.last + dx).ceil - 1 (max_x - min_x).times {|sx| next if passable?(min_x + sx, @y, 6) dx = (min_x + sx + 1) - range_x.last check_event_trigger_touch(min_x + sx + 1, @y) break } elsif dx < 0 # 左方向 min_x, max_x = (range_x.first + dx).floor, range_x.last.ceil - 1 (max_x - min_x).times {|sx| next if passable?(max_x - sx, @y, 4) dx = (max_x - sx) - range_x.first check_event_trigger_touch(max_x - sx - 1, @y) break } end if dy > 0 # 下方向 min_y, max_y = range_y.first.floor, (range_y.last + dy).ceil - 1 (max_y - min_y).times {|sy| next if passable?(@x, min_y + sy, 2) dy = (min_y + sy + 1) - range_y.last check_event_trigger_touch(@x, min_y + sy + 1) break } elsif dy < 0 # 上方向 min_y, max_y = (range_y.first + dy).floor, range_y.last.ceil - 1 (max_y - min_y).times {|sy| next if passable?(@x, max_y - sy, 8) dy = (max_y - sy) - range_y.first check_event_trigger_touch(@x, max_y - sy - 1) break } end # 座標を変化させる @x += dx @y += dy # 不要な桁を切り捨て @x, @y = @x.rounddown(-3), @y.rounddown(-3) # 1 マス分以上座標が変化した場合、歩数増加 increase_steps if @x.truncate != last_x or @y.truncate != last_y end #-------------------------------------------------------------------------- # ● 下を向く #-------------------------------------------------------------------------- alias :__orig_dms__turn_down :turn_down unless $@ def turn_down __orig_dms__turn_down @real_direction = 2 unless @direction_fix end #-------------------------------------------------------------------------- # ● 左を向く #-------------------------------------------------------------------------- alias :__orig_dms__turn_left :turn_left unless $@ def turn_left __orig_dms__turn_left @real_direction = 4 unless @direction_fix end #-------------------------------------------------------------------------- # ● 右を向く #-------------------------------------------------------------------------- alias :__orig_dms__turn_right :turn_right unless $@ def turn_right __orig_dms__turn_right @real_direction = 6 unless @direction_fix end #-------------------------------------------------------------------------- # ● 上を向く #-------------------------------------------------------------------------- alias :__orig_dms__turn_up :turn_up unless $@ def turn_up __orig_dms__turn_up @real_direction = 8 unless @direction_fix end end #============================================================================== # ■ Sprite_Character #============================================================================== class Sprite_Character < RPG::Sprite #-------------------------------------------------------------------------- # ● フレーム更新 #-------------------------------------------------------------------------- alias :__orig_dms__update :update def update # タイル ID、ファイル名、色相のどれかが現在のものと異なる場合 if (@tile_id != @character.tile_id) or (@character_name != @character.character_name) or (@character_hue != @character.character_hue) # タイル ID が無効でキャラクターがプレイヤーの場合 flag = true if @character.tile_id < 384 and @character.is_a?(Game_Player) end __orig_dms__update # 変更フラグが有効な場合 @character.width, @character.height = @cw.quo(32), 1 if flag end end