battle-maiden-mizuki/Scripts/Game_CharacterBase.rb
2025-06-17 11:57:06 -05:00

443 lines
19 KiB
Ruby
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#==============================================================================
# ■ 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 # タイル ID0 なら無効)
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 > 18 - 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