#============================================================================== # ■ Game_CharacterBase #------------------------------------------------------------------------------ #  キャラクターを扱う基本のクラスです。全てのキャラクターに共通する、座標やグ # ラフィックなどの基本的な情報を保持します。 #============================================================================== class Game_CharacterBase #-------------------------------------------------------------------------- # ● 公開インスタンス変数 #-------------------------------------------------------------------------- attr_reader :id # ID attr_reader :x # マップ X 座標(論理座標) attr_reader :y # マップ Y 座標(論理座標) attr_reader :real_x # マップ X 座標(実座標) attr_reader :real_y # マップ Y 座標(実座標) attr_reader :tile_id # タイル ID(0 なら無効) attr_reader :character_name # 歩行グラフィック ファイル名 attr_reader :character_index # 歩行グラフィック インデックス attr_reader :move_speed # 移動速度 attr_reader :move_frequency # 移動頻度 attr_reader :walk_anime # 歩行アニメ attr_reader :step_anime # 足踏みアニメ attr_reader :direction_fix # 向き固定 attr_reader :opacity # 不透明度 attr_reader :blend_type # 合成方法 attr_reader :direction # 向き attr_reader :pattern # パターン attr_reader :priority_type # プライオリティタイプ attr_reader :through # すり抜け attr_reader :bush_depth # 茂み深さ attr_accessor :animation_id # アニメーション ID attr_accessor :balloon_id # フキダシアイコン ID attr_accessor :transparent # 透明状態 #-------------------------------------------------------------------------- # ● オブジェクト初期化 #-------------------------------------------------------------------------- def initialize init_public_members init_private_members end #-------------------------------------------------------------------------- # ● 公開メンバ変数の初期化 #-------------------------------------------------------------------------- def init_public_members @id = 0 @x = 0 @y = 0 @real_x = 0 @real_y = 0 @tile_id = 0 @character_name = "" @character_index = 0 @move_speed = 4 @move_frequency = 6 @walk_anime = true @step_anime = false @direction_fix = false @opacity = 255 @blend_type = 0 @direction = 2 @pattern = 1 @priority_type = 1 @through = false @bush_depth = 0 @animation_id = 0 @balloon_id = 0 @transparent = false end #-------------------------------------------------------------------------- # ● 非公開メンバ変数の初期化 #-------------------------------------------------------------------------- def init_private_members @original_direction = 2 # 元の向き @original_pattern = 1 # 元のパターン @anime_count = 0 # アニメカウント @stop_count = 0 # 停止カウント @jump_count = 0 # ジャンプカウント @jump_peak = 0 # ジャンプの頂点のカウント @locked = false # ロックフラグ @prelock_direction = 0 # ロック前の向き @move_succeed = true # 移動成功フラグ end #-------------------------------------------------------------------------- # ● 座標一致判定 #-------------------------------------------------------------------------- def pos?(x, y) @x == x && @y == y end #-------------------------------------------------------------------------- # ● 座標一致と「すり抜け OFF」判定(nt = No Through) #-------------------------------------------------------------------------- def pos_nt?(x, y) pos?(x, y) && !@through end #-------------------------------------------------------------------------- # ● プライオリティ[通常キャラと同じ]判定 #-------------------------------------------------------------------------- def normal_priority? @priority_type == 1 end #-------------------------------------------------------------------------- # ● 移動中判定 #-------------------------------------------------------------------------- def moving? @real_x != @x || @real_y != @y end #-------------------------------------------------------------------------- # ● ジャンプ中判定 #-------------------------------------------------------------------------- def jumping? @jump_count > 0 end #-------------------------------------------------------------------------- # ● ジャンプの高さを計算 #-------------------------------------------------------------------------- def jump_height (@jump_peak * @jump_peak - (@jump_count - @jump_peak).abs ** 2) / 2 end #-------------------------------------------------------------------------- # ● 停止中判定 #-------------------------------------------------------------------------- def stopping? !moving? && !jumping? end #-------------------------------------------------------------------------- # ● 移動速度の取得(ダッシュを考慮) #-------------------------------------------------------------------------- def real_move_speed @move_speed + (dash? ? 1 : 0) end #-------------------------------------------------------------------------- # ● 1 フレームあたりの移動距離を計算 #-------------------------------------------------------------------------- def distance_per_frame 2 ** real_move_speed / 256.0 end #-------------------------------------------------------------------------- # ● ダッシュ状態判定 #-------------------------------------------------------------------------- def dash? return false end #-------------------------------------------------------------------------- # ● デバッグすり抜け状態判定 #-------------------------------------------------------------------------- def debug_through? return false end #-------------------------------------------------------------------------- # ● 姿勢の矯正 #-------------------------------------------------------------------------- def straighten @pattern = 1 if @walk_anime || @step_anime @anime_count = 0 end #-------------------------------------------------------------------------- # ● 逆方向の取得 # d : 方向(2,4,6,8) #-------------------------------------------------------------------------- def reverse_dir(d) return 10 - d end #-------------------------------------------------------------------------- # ● 通行可能判定 # d : 方向(2,4,6,8) #-------------------------------------------------------------------------- def passable?(x, y, d) x2 = $game_map.round_x_with_direction(x, d) y2 = $game_map.round_y_with_direction(y, d) return false unless $game_map.valid?(x2, y2) return true if @through || debug_through? return false unless map_passable?(x, y, d) return false unless map_passable?(x2, y2, reverse_dir(d)) return false if collide_with_characters?(x2, y2) return true end #-------------------------------------------------------------------------- # ● 斜めの通行可能判定 # horz : 横方向(4 or 6) # vert : 縦方向(2 or 8) #-------------------------------------------------------------------------- def diagonal_passable?(x, y, horz, vert) x2 = $game_map.round_x_with_direction(x, horz) y2 = $game_map.round_y_with_direction(y, vert) (passable?(x, y, vert) && passable?(x, y2, horz)) || (passable?(x, y, horz) && passable?(x2, y, vert)) end #-------------------------------------------------------------------------- # ● マップ通行可能判定 # d : 方向(2,4,6,8) #-------------------------------------------------------------------------- def map_passable?(x, y, d) $game_map.passable?(x, y, d) end #-------------------------------------------------------------------------- # ● キャラクターとの衝突判定 #-------------------------------------------------------------------------- def collide_with_characters?(x, y) collide_with_events?(x, y) || collide_with_vehicles?(x, y) end #-------------------------------------------------------------------------- # ● イベントとの衝突判定 #-------------------------------------------------------------------------- def collide_with_events?(x, y) $game_map.events_xy_nt(x, y).any? do |event| event.normal_priority? || self.is_a?(Game_Event) end end #-------------------------------------------------------------------------- # ● 乗り物との衝突判定 #-------------------------------------------------------------------------- def collide_with_vehicles?(x, y) $game_map.boat.pos_nt?(x, y) || $game_map.ship.pos_nt?(x, y) end #-------------------------------------------------------------------------- # ● 指定位置に移動 #-------------------------------------------------------------------------- def moveto(x, y) @x = x % $game_map.width @y = y % $game_map.height @real_x = @x @real_y = @y @prelock_direction = 0 straighten update_bush_depth end #-------------------------------------------------------------------------- # ● 指定方向に向き変更 # d : 方向(2,4,6,8) #-------------------------------------------------------------------------- def set_direction(d) @direction = d if !@direction_fix && d != 0 @stop_count = 0 end #-------------------------------------------------------------------------- # ● タイル判定 #-------------------------------------------------------------------------- def tile? @tile_id > 0 && @priority_type == 0 end #-------------------------------------------------------------------------- # ● オブジェクトキャラクター判定 #-------------------------------------------------------------------------- def object_character? @tile_id > 0 || @character_name[0, 1] == '!' end #-------------------------------------------------------------------------- # ● タイルの位置から上にずらすピクセル数を取得 #-------------------------------------------------------------------------- def shift_y object_character? ? 0 : 4 end #-------------------------------------------------------------------------- # ● 画面 X 座標の取得 #-------------------------------------------------------------------------- def screen_x $game_map.adjust_x(@real_x) * 32 + 16 end #-------------------------------------------------------------------------- # ● 画面 Y 座標の取得 #-------------------------------------------------------------------------- def screen_y $game_map.adjust_y(@real_y) * 32 + 32 - shift_y - jump_height end #-------------------------------------------------------------------------- # ● 画面 Z 座標の取得 #-------------------------------------------------------------------------- def screen_z @priority_type * 100 end #-------------------------------------------------------------------------- # ● フレーム更新 #-------------------------------------------------------------------------- def update update_animation return update_jump if jumping? return update_move if moving? return update_stop end #-------------------------------------------------------------------------- # ● ジャンプ時の更新 #-------------------------------------------------------------------------- def update_jump @jump_count -= 1 @real_x = (@real_x * @jump_count + @x) / (@jump_count + 1.0) @real_y = (@real_y * @jump_count + @y) / (@jump_count + 1.0) update_bush_depth if @jump_count == 0 @real_x = @x = $game_map.round_x(@x) @real_y = @y = $game_map.round_y(@y) end end #-------------------------------------------------------------------------- # ● 移動時の更新 #-------------------------------------------------------------------------- def update_move @real_x = [@real_x - distance_per_frame, @x].max if @x < @real_x @real_x = [@real_x + distance_per_frame, @x].min if @x > @real_x @real_y = [@real_y - distance_per_frame, @y].max if @y < @real_y @real_y = [@real_y + distance_per_frame, @y].min if @y > @real_y update_bush_depth unless moving? end #-------------------------------------------------------------------------- # ● 停止時の更新 #-------------------------------------------------------------------------- def update_stop @stop_count += 1 unless @locked end #-------------------------------------------------------------------------- # ● 歩行/足踏みアニメの更新 #-------------------------------------------------------------------------- def update_animation update_anime_count if @anime_count > 27 - real_move_speed * 2 update_anime_pattern @anime_count = 0 end end #-------------------------------------------------------------------------- # ● アニメカウントの更新 #-------------------------------------------------------------------------- def update_anime_count if moving? && @walk_anime @anime_count += 1.5 elsif @step_anime || @pattern != @original_pattern @anime_count += 1 end end #-------------------------------------------------------------------------- # ● アニメパターンの更新 #-------------------------------------------------------------------------- def update_anime_pattern if !@step_anime && @stop_count > 0 @pattern = @original_pattern else @pattern = (@pattern + 1) % 4 end end #-------------------------------------------------------------------------- # ● 梯子判定 #-------------------------------------------------------------------------- def ladder? $game_map.ladder?(@x, @y) end #-------------------------------------------------------------------------- # ● 茂み深さの更新 #-------------------------------------------------------------------------- def update_bush_depth if normal_priority? && !object_character? && bush? && !jumping? @bush_depth = 8 unless moving? else @bush_depth = 0 end end #-------------------------------------------------------------------------- # ● 茂み判定 #-------------------------------------------------------------------------- def bush? $game_map.bush?(@x, @y) end #-------------------------------------------------------------------------- # ● 地形タグの取得 #-------------------------------------------------------------------------- def terrain_tag $game_map.terrain_tag(@x, @y) end #-------------------------------------------------------------------------- # ● リージョン ID の取得 #-------------------------------------------------------------------------- def region_id $game_map.region_id(@x, @y) end #-------------------------------------------------------------------------- # ● 歩数増加 #-------------------------------------------------------------------------- def increase_steps set_direction(8) if ladder? @stop_count = 0 update_bush_depth end #-------------------------------------------------------------------------- # ● グラフィックの変更 # character_name : 新しい歩行グラフィック ファイル名 # character_index : 新しい歩行グラフィック インデックス #-------------------------------------------------------------------------- def set_graphic(character_name, character_index) @tile_id = 0 @character_name = character_name @character_index = character_index @original_pattern = 1 end #-------------------------------------------------------------------------- # ● 正面の接触イベントの起動判定 #-------------------------------------------------------------------------- def check_event_trigger_touch_front x2 = $game_map.round_x_with_direction(@x, @direction) y2 = $game_map.round_y_with_direction(@y, @direction) check_event_trigger_touch(x2, y2) end #-------------------------------------------------------------------------- # ● 接触イベントの起動判定 #-------------------------------------------------------------------------- def check_event_trigger_touch(x, y) return false end #-------------------------------------------------------------------------- # ● まっすぐに移動 # d : 方向(2,4,6,8) # turn_ok : その場での向き変更を許可 #-------------------------------------------------------------------------- def move_straight(d, turn_ok = true) @move_succeed = passable?(@x, @y, d) if @move_succeed set_direction(d) @x = $game_map.round_x_with_direction(@x, d) @y = $game_map.round_y_with_direction(@y, d) @real_x = $game_map.x_with_direction(@x, reverse_dir(d)) @real_y = $game_map.y_with_direction(@y, reverse_dir(d)) increase_steps elsif turn_ok set_direction(d) check_event_trigger_touch_front end end #-------------------------------------------------------------------------- # ● 斜めに移動 # horz : 横方向(4 or 6) # vert : 縦方向(2 or 8) #-------------------------------------------------------------------------- def move_diagonal(horz, vert) @move_succeed = diagonal_passable?(x, y, horz, vert) if @move_succeed @x = $game_map.round_x_with_direction(@x, horz) @y = $game_map.round_y_with_direction(@y, vert) @real_x = $game_map.x_with_direction(@x, reverse_dir(horz)) @real_y = $game_map.y_with_direction(@y, reverse_dir(vert)) increase_steps end set_direction(horz) if @direction == reverse_dir(horz) set_direction(vert) if @direction == reverse_dir(vert) end end