=begin ▼ 乗り物擬似3D化 メインスクリプト ver. 3.0.1 RPGツクールVXAce用スクリプト 制作 : 木星ペンギン URL : http://woodpenguin.blog.fc2.com/ #////////////////////////////////////////////////////////////////////////////// # # 設定項目なし # #////////////////////////////////////////////////////////////////////////////// ===メモ=== 2x 行目〜 : モジュール 5x 行目〜 : ゲームオブジェクト 98x 行目〜 : スプライト 139x 行目〜 : ウィンドウ 141x 行目〜 : シーン =end #━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ # # ▼ モジュール # #━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ module WdTk::Veh3D #-------------------------------------------------------------------------- # ● フレームカウントのリセット #-------------------------------------------------------------------------- def self.reset @@frame_count = 0 @@need_update = true end #-------------------------------------------------------------------------- # ● 更新 #-------------------------------------------------------------------------- def self.update @@frame_count += FrameRate @@need_update = @@frame_count >= 60 @@frame_count %= 60 end #-------------------------------------------------------------------------- # ● 更新が必要かどうか #-------------------------------------------------------------------------- def self.need_update? @@need_update end end #━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ # # ▼ ゲームオブジェクト # #━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ #============================================================================== # ■ Game_Map #============================================================================== class Game_Map #-------------------------------------------------------------------------- # ☆ 乗り物の作成 #-------------------------------------------------------------------------- def create_vehicles @vehicles = WdTk::Veh3D.data.collect {|key,| Game_Vehicle.new(key) } end #-------------------------------------------------------------------------- # ☆ 乗り物の取得 #-------------------------------------------------------------------------- def vehicle(type) @vehicles.find {|vehicle| vehicle.type == type } end #-------------------------------------------------------------------------- # ● 表示位置の設定 (ループ判定なし) #-------------------------------------------------------------------------- def set_pos(x, y) @display_x = x @display_y = y @parallax_x = x @parallax_y = y end #-------------------------------------------------------------------------- # ● 乗り物の通行可能判定 #-------------------------------------------------------------------------- def vehicle_passable?(x, y, types, through) return true unless types all_tiles(x, y).each do |tile_id| if tile_id >= 2048 return types.include?((tile_id - 2048) / 48) else flag = tileset.flags[tile_id] next if flag & 0x10 != 0 return (through && flag & 0x0f == 0) end end return false end #-------------------------------------------------------------------------- # ● 着陸可能判定 #-------------------------------------------------------------------------- def land_ok?(x, y, denial) return false if denial && denial.include?(autotile_type(x, y, 1)) return false if denial && denial.include?(autotile_type(x, y, 0)) return check_passage(x, y, 0x0f) end end #============================================================================== # ■ Game_CharacterBase #============================================================================== class Game_CharacterBase #-------------------------------------------------------------------------- # ☆ 乗り物との衝突判定 #-------------------------------------------------------------------------- def collide_with_vehicles?(x, y) $game_map.vehicles.any? {|v| v.pos_nt?(x, y) && !v.get_here? } end end #============================================================================== # ■ Game_Player #============================================================================== class Game_Player #-------------------------------------------------------------------------- # ● 公開インスタンス変数 #-------------------------------------------------------------------------- attr_reader :keep_vehicles attr_accessor :in_vehicle #-------------------------------------------------------------------------- # ◯ オブジェクト初期化 #-------------------------------------------------------------------------- alias _wdtk_veh3d_initialize initialize def initialize _wdtk_veh3d_initialize @keep_vehicles = [] end #-------------------------------------------------------------------------- # ● 搭乗中のタイプかどうか #-------------------------------------------------------------------------- def driving?(type) @in_vehicle && @vehicle_type == type end #-------------------------------------------------------------------------- # ◯ 場所移動の実行 #-------------------------------------------------------------------------- alias _wdtk_veh3d_perform_transfer perform_transfer def perform_transfer if transfer? && vehicle vehicle.set_direction(@new_direction) _wdtk_veh3d_perform_transfer vehicle.sync_with_player else _wdtk_veh3d_perform_transfer end end #-------------------------------------------------------------------------- # ☆ 飛行する乗り物に乗っているかどうか #-------------------------------------------------------------------------- def in_airship? @in_vehicle && vehicle.flight? end #-------------------------------------------------------------------------- # ◯ フレーム更新 #-------------------------------------------------------------------------- alias _wdtk_veh3d_update update def update if @in_vehicle return if !movable? || $game_map.interpreter.running? vehicle.process_control last_x = @x last_y = @y @x = @real_x = vehicle.x.round @y = @real_y = vehicle.y.round update_vehicle_moving(last_x != @x || last_y != @y) else _wdtk_veh3d_update end end #-------------------------------------------------------------------------- # ● 乗り物で移動した場合の処理 # tile_moving : タイルを移動したかどうか #-------------------------------------------------------------------------- def update_vehicle_moving(tile_moving) if tile_moving increase_steps vehicle.update_bush_depth end return if $game_map.interpreter.running? if tile_moving return if check_touch_event end return if vehicle.process_handling update_encounter if tile_moving end #-------------------------------------------------------------------------- # ☆ 乗り物に乗る動作の更新 #-------------------------------------------------------------------------- def update_vehicle_get_on if !@followers.gathering? && !moving? @vehicle_getting_on = false @transparent = true vehicle.get_on end end #-------------------------------------------------------------------------- # ☆ エンカウントの更新 #-------------------------------------------------------------------------- def update_encounter return if $TEST && Input.press?(:CTRL) return if $game_party.encounter_none? return if @in_vehicle && vehicle.encounter_none? return if @move_route_forcing @encounter_count -= encounter_progress_value end #-------------------------------------------------------------------------- # ☆ エンカウント進行値の取得 #-------------------------------------------------------------------------- def encounter_progress_value value = $game_map.bush?(@x, @y) ? 2 : 1 value *= 0.5 if $game_party.encounter_half? value *= vehicle.encount_rate / 100.0 if @in_vehicle value end #-------------------------------------------------------------------------- # ◯ 決定ボタンによるイベント起動判定 #-------------------------------------------------------------------------- alias _wdtk_veh3d_check_action_event check_action_event def check_action_event if in_airship? check_event_trigger_here([0]) $game_map.setup_starting_event else _wdtk_veh3d_check_action_event end end #-------------------------------------------------------------------------- # ☆ 乗り物に乗る # 現在乗り物に乗っていないことが前提。 #-------------------------------------------------------------------------- def get_on_vehicle front_x = $game_map.round_x_with_direction(@x, @direction) front_y = $game_map.round_y_with_direction(@y, @direction) $game_map.vehicles.each do |veh| next if veh.control if veh.get_here? @vehicle_type = veh.type if veh.pos?(@x, @y) else @vehicle_type = veh.type if veh.pos?(front_x, front_y) end end if vehicle @vehicle_getting_on = true force_move_forward unless vehicle.get_here? @followers.gather end @vehicle_getting_on end #-------------------------------------------------------------------------- # ☆ 乗り物から降りる #-------------------------------------------------------------------------- def get_off_vehicle if vehicle.land_ok?(@x, @y, vehicle.angle_dir) set_direction(vehicle.sync_dir? ? vehicle.angle_dir : 2) @followers.synchronize(@x, @y, @direction) vehicle.get_off @vehicle_getting_off = true make_encounter_count @followers.gather end @vehicle_getting_off end #-------------------------------------------------------------------------- # ● 乗り物開始処理 #-------------------------------------------------------------------------- def on_vehicle_start @in_vehicle = true if @vehicle_type == :walk @vehicle_type = @keep_vehicles.pop @transparent = true @followers.update end _wdtk_veh3d_perform_transfer vehicle.on_vehicle_start end #-------------------------------------------------------------------------- # ● 乗り物終了処理 #-------------------------------------------------------------------------- def on_vehicle_end @in_vehicle = false center(@x, @y) vehicle.on_vehicle_end if @keep_vehicles.include?(@vehicle_type) vehicle.get_off @vehicle_type = :walk @transparent = false @followers.update elsif !vehicle.get_here? force_move_forward @transparent = false end $game_map.autoplay _wdtk_veh3d_perform_transfer end #-------------------------------------------------------------------------- # ● 記憶した乗り物に乗る #-------------------------------------------------------------------------- def get_on_keep_vehicle sym = @keep_vehicles[-1] $game_map.vehicle(sym).transfer if sym end #-------------------------------------------------------------------------- # ● 現在の乗り物を記憶 #-------------------------------------------------------------------------- def keep_vehicle @keep_vehicles.delete(@vehicle_type) @keep_vehicles << @vehicle_type end #-------------------------------------------------------------------------- # ● 記憶した乗り物の削除 #-------------------------------------------------------------------------- def delete_keep_vehicle sym = @keep_vehicles.pop $game_map.vehicle(sym).on_vehicle_end if sym end end #============================================================================== # ■ Game_Vehicle #============================================================================== class Game_Vehicle #-------------------------------------------------------------------------- # ● モジュール #-------------------------------------------------------------------------- include Math #-------------------------------------------------------------------------- # ● 公開インスタンス変数 #-------------------------------------------------------------------------- attr_reader :type attr_reader :angle attr_reader :drive_direction attr_reader :control #-------------------------------------------------------------------------- # ◯ オブジェクト初期化 #-------------------------------------------------------------------------- alias _wdtk_veh3d_initialize initialize def initialize(type) _wdtk_veh3d_initialize(type) @drive_speed = 0 @drive_direction = 5 @angle = 0 @angle_speed = 0 @slide_speed = 0 @control = false end #-------------------------------------------------------------------------- # ● 乗り物データの取得 #-------------------------------------------------------------------------- def param(sym) WdTk::Veh3D.data[@type][sym] end #-------------------------------------------------------------------------- # ☆ 移動速度の初期化 #-------------------------------------------------------------------------- def init_move_speed @move_speed = param(:move_speed) end #-------------------------------------------------------------------------- # ◯ システム設定の取得 #-------------------------------------------------------------------------- alias _wdtk_veh3d_system_vehicle system_vehicle def system_vehicle _wdtk_veh3d_system_vehicle || param(:system) end #-------------------------------------------------------------------------- # ● 移動中判定 #-------------------------------------------------------------------------- def moving? @control ? @drive_speed != 0 || @angle_speed != 0 : super end #-------------------------------------------------------------------------- # ● 1 フレームあたりの移動距離を計算 #-------------------------------------------------------------------------- def distance_per_frame super * 60 / WdTk::Veh3D::FrameRate end #-------------------------------------------------------------------------- # ● デバッグすり抜け状態判定 #-------------------------------------------------------------------------- def debug_through? $TEST && Input.press?(:CTRL) end #-------------------------------------------------------------------------- # ● 乗り物との衝突判定 #-------------------------------------------------------------------------- def collide_with_vehicles?(x, y) $game_map.vehicles.any? {|v| v != self && v.pos_nt?(x, y) } end #-------------------------------------------------------------------------- # ● 指定方向に向き変更 # d : 方向(2,4,6,8) #-------------------------------------------------------------------------- def set_direction(d) super if @driving && d != 0 case @direction when 2; @angle = 180 when 4; @angle = 90 when 6; @angle = 270 when 8; @angle = 0 end stop end end #-------------------------------------------------------------------------- # ● グラフィックインデックスの取得 #-------------------------------------------------------------------------- def vehicle_index case @drive_direction when 5; param(:vehicle_index1) || @character_index when 2,4,6,8; param(:vehicle_index2) || param(:vehicle_index1) || @character_index when 1,3,7,9; param(:vehicle_index3) || @character_index end end #-------------------------------------------------------------------------- # ● 場所移動の予約 #-------------------------------------------------------------------------- def transfer $game_player.reserve_transfer(@map_id, @x.round, @y.round) last_angle = @angle get_on @angle = last_angle end #-------------------------------------------------------------------------- # ◯ 乗り物に乗る #-------------------------------------------------------------------------- alias _wdtk_veh3d_get_on get_on def get_on _wdtk_veh3d_get_on @walk_anime = param(:walk_anime) != false @step_anime = param(:step_anime) != false @drive_speed = 0 @drive_direction = 5 @slide_speed = 0 @angle = 0 set_direction($game_player.direction) if sync_dir? @angle_speed = 0 SceneManager.goto(Scene_Vehicle) end #-------------------------------------------------------------------------- # ◯ 乗り物から降りる #-------------------------------------------------------------------------- alias _wdtk_veh3d_get_off get_off def get_off _wdtk_veh3d_get_off @step_anime = param(:step_anime) != false SceneManager.goto(Scene_Map) end #-------------------------------------------------------------------------- # ● 乗り物開始処理 #-------------------------------------------------------------------------- def on_vehicle_start unless @control @control = true if flight? @altitude = [[@altitude, max_altitude].min, min_altitude].max else @altitude = 8 end end $game_switches[param(:switch_id)] = true if param(:switch_id) end #-------------------------------------------------------------------------- # ● 乗り物終了処理 #-------------------------------------------------------------------------- def on_vehicle_end unless @driving @control = false @altitude = flight? ? 32 : 0 moveto(@x.round, @y.round) end $game_switches[param(:switch_id)] = false if param(:switch_id) refresh end #-------------------------------------------------------------------------- # ● 停止 #-------------------------------------------------------------------------- def stop @drive_speed = 0 @angle_speed = 0 @stop_count = 0 end #-------------------------------------------------------------------------- # ● 移動可能判定 #-------------------------------------------------------------------------- def movable? @driving end #-------------------------------------------------------------------------- # ☆ リフレッシュ #-------------------------------------------------------------------------- def refresh if @driving @map_id = $game_map.map_id #sync_with_player stop elsif @map_id == $game_map.map_id moveto(@x, @y) end if flight? @priority_type = @driving ? 2 : 0 else @priority_type = 1 end if @control @drive_direction = 5 @walk_anime = param(:walk_anime) != false @step_anime = param(:step_anime) != false else @walk_anime = @step_anime = false end end #-------------------------------------------------------------------------- # ● 飛行するかどうか #-------------------------------------------------------------------------- def flight? param(:flight) end #-------------------------------------------------------------------------- # ● 搭乗時向き変更するかどうか #-------------------------------------------------------------------------- def sync_dir? param(:sync_dir) end #-------------------------------------------------------------------------- # ● 同一による搭乗かどうか #-------------------------------------------------------------------------- def get_here? param(:get_here) end #-------------------------------------------------------------------------- # ● エンカウント率の取得 #-------------------------------------------------------------------------- def encount_rate param(:encount) || 0 end #-------------------------------------------------------------------------- # ● エンカウント無効? #-------------------------------------------------------------------------- def encounter_none? encount_rate == 0 end #-------------------------------------------------------------------------- # ● 角度から方向の取得 #-------------------------------------------------------------------------- def angle_dir case (@angle + 45).to_i / 90 when 0,4; 8 when 1; 4 when 2; 2 when 3; 6 end end #-------------------------------------------------------------------------- # ☆ フレーム更新 #-------------------------------------------------------------------------- def update if @control update_animation if $game_player.driving?(@type) && !@driving && flight? if @altitude > 32 || Graphics.frame_count % (5 - @altitude / 8) == 0 @altitude -= 1 end end else super update_airship_altitude if flight? @step_anime = param(:step_anime) != false if @driving end end #-------------------------------------------------------------------------- # ● 乗り物操縦時の処理 #-------------------------------------------------------------------------- def process_control @drive_direction = 5 if Input.press?(param(:inp_forward1)) || Input.press?(param(:inp_forward2)) process_forward elsif Input.press?(param(:inp_backward)) process_backward else process_reduce_drive end if Input.press?(param(:inp_left)) process_left elsif Input.press?(param(:inp_right)) process_right else process_reduce_slide end unless Input.press?(param(:inp_horz)) turn = 0 turn += 1 if Input.press?(param(:inp_turnleft1)) turn += 1 if Input.press?(param(:inp_turnleft2)) turn -= 1 if Input.press?(param(:inp_turnright1)) turn -= 1 if Input.press?(param(:inp_turnright2)) process_turn(turn) if flight? process_up if Input.press?(param(:inp_up)) process_down if Input.press?(param(:inp_down)) end else process_reduce_turn end if WdTk::Veh3D.need_update? update_angle if @drive_speed != 0 update_drive(@angle, distance_per_frame * @drive_speed / 32) end if @slide_speed != 0 update_drive(@angle + 90, distance_per_frame * @slide_speed / 32) elsif @drive_speed == 0 && Input.press?(param(:inp_horz)) process_horz end end update_stop unless moving? end #-------------------------------------------------------------------------- # ● 操縦以外の処理 #-------------------------------------------------------------------------- def process_handling if @drive_speed <= 12 if Input.trigger?(param(:inp_get_off)) || (!param(:inp_get_off) && @altitude <= (min_altitude + 8) && Input.press?(param(:inp_down))) return stop if $game_player.get_off_vehicle end if Input.trigger?(param(:inp_event)) $game_player.set_direction(angle_dir) return stop if $game_player.check_action_event end end if Input.trigger?(param(:inp_menu)) return process_menu end end #-------------------------------------------------------------------------- # ● 前進の処理 #-------------------------------------------------------------------------- def process_forward @drive_speed += 1 if @drive_speed < 32 @stop_count = 0 end #-------------------------------------------------------------------------- # ● 後退の処理 #-------------------------------------------------------------------------- def process_backward @drive_speed -= 1 if @drive_speed > -16 @stop_count = 0 end #-------------------------------------------------------------------------- # ● 速度低下の処理 #-------------------------------------------------------------------------- def process_reduce_drive @drive_speed += (0 <=> @drive_speed) end #-------------------------------------------------------------------------- # ● 左移動の処理 #-------------------------------------------------------------------------- def process_left @slide_speed += 1 if @slide_speed < 16 @stop_count = 0 end #-------------------------------------------------------------------------- # ● 右移動の処理 #-------------------------------------------------------------------------- def process_right @slide_speed -= 1 if @slide_speed > -16 @stop_count = 0 end #-------------------------------------------------------------------------- # ● 横移動低下の処理 #-------------------------------------------------------------------------- def process_reduce_slide @slide_speed += (0 <=> @slide_speed) end #-------------------------------------------------------------------------- # ● 旋回の処理 #-------------------------------------------------------------------------- def process_turn(speed) if @angle_speed < 24 * speed @angle_speed += 1 if @angle_speed < 32 elsif @angle_speed > 24 * speed @angle_speed -= 1 if @angle_speed > -32 end if speed != 0 @drive_direction += (0 <=> speed) if (param(:dir_type) || 0) >= 1 @stop_count = 0 end end #-------------------------------------------------------------------------- # ● 旋回低下の処理 #-------------------------------------------------------------------------- def process_reduce_turn @angle_speed += (0 <=> @angle_speed) end #-------------------------------------------------------------------------- # ● 上昇の処理 #-------------------------------------------------------------------------- def process_up @altitude += 1 if @altitude < max_altitude @drive_direction += 3 if param(:dir_type) >= 2 end #-------------------------------------------------------------------------- # ● 下降の処理 #-------------------------------------------------------------------------- def process_down @altitude -= 1 if @altitude > min_altitude @drive_direction -= 3 if param(:dir_type) >= 2 end #-------------------------------------------------------------------------- # ● メニュー呼び出しの処理 #-------------------------------------------------------------------------- def process_menu Sound.play_ok SceneManager.call(Scene_Menu) Window_MenuCommand::init_command_position end #-------------------------------------------------------------------------- # ● 水平移動の処理 #-------------------------------------------------------------------------- def process_horz case Input.dir8 when 1; angle = (@angle + 135) % 360 when 2; angle = (@angle + 180) % 360 when 3; angle = (@angle + 225) % 360 when 4; angle = (@angle + 90) % 360 when 6; angle = (@angle + 270) % 360 when 7; angle = (@angle + 45) % 360 when 8; angle = @angle when 9; angle = (@angle + 315) % 360 else return end update_drive(angle, distance_per_frame / 3) end #-------------------------------------------------------------------------- # ● 向きの更新 #-------------------------------------------------------------------------- def update_angle speed = param(:turning) * @angle_speed / 128.0 * 60 / WdTk::Veh3D::FrameRate @angle = (@angle + speed) % 360 end #-------------------------------------------------------------------------- # ● 移動時の更新 #-------------------------------------------------------------------------- def update_drive(angle, distance) x1 = $game_map.round_x(@x.round) y1 = $game_map.round_y(@y.round) tx = $game_map.round_x(@x - sin(angle * PI / 180) * distance) ty = $game_map.round_y(@y - cos(angle * PI / 180) * distance) x2 = round_x_with_pos(tx) y2 = round_y_with_pos(ty) if x1 == x2 || vehicle_passable?(x2, y1) @x = @real_x = tx if (y1 == y2 || vehicle_passable?(x1, y2)) && (x1 == x2 || vehicle_passable?(x2, y2)) @y = @real_y = ty end elsif y1 == y2 || vehicle_passable?(x1, y2) @y = @real_y = ty end end #-------------------------------------------------------------------------- # ☆ 飛行船の最大高度を取得 #-------------------------------------------------------------------------- def max_altitude param(:max_altitude) || 100 end #-------------------------------------------------------------------------- # ● 飛行船の最低高度を取得 #-------------------------------------------------------------------------- def min_altitude param(:min_altitude) || 20 end #-------------------------------------------------------------------------- # ☆ 接岸/着陸可能判定 # d : 方向(2,4,6,8) #-------------------------------------------------------------------------- def land_ok?(x, y, d) if get_here? return false unless $game_map.land_ok?(x, y, param(:land_denial)) return false unless $game_map.events_xy(x, y).empty? return false if collide_with_vehicles?(x, y) else 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 false unless $game_map.passable?(x2, y2, reverse_dir(d)) return false if collide_with_characters?(x2, y2) end return true end #-------------------------------------------------------------------------- # ● 通行可能判定 #-------------------------------------------------------------------------- def vehicle_passable?(x2, y2) return false unless $game_map.valid?(x2, y2) return true if @through || debug_through? return false unless map_passable?(x2, y2, 0) if !flight? && collide_with_events?(x2, y2) $game_player.check_event_trigger_touch(x2, y2) stop if $game_map.any_event_starting? return false end return false if !flight? && collide_with_vehicles?(x2, y2) return true end #-------------------------------------------------------------------------- # ● 特定の方向にずらした座標の計算(ループ補正あり) #-------------------------------------------------------------------------- def round_x_with_pos(x) return $game_map.round_x(x.floor) if x < @x && x % 1 < 0.75 return $game_map.round_x(x.ceil) if x > @x && x % 1 > 0.25 return $game_map.round_x(x.round) end def round_y_with_pos(y) return $game_map.round_y(y.floor) if y < @y && y % 1 < 0.75 return $game_map.round_y(y.ceil) if y > @y && y % 1 > 0.25 return $game_map.round_y(y.round) end #-------------------------------------------------------------------------- # ● 乗り物のマップ通行可能判定 #-------------------------------------------------------------------------- def map_passable?(x, y, d) $game_map.vehicle_passable?(x, y, param(:passage1), param(:passage2)) end #-------------------------------------------------------------------------- # ● 角度からラジアンの取得 #-------------------------------------------------------------------------- def angle_radian if @angle < 90 sx = [@angle, 45].min elsif @angle < 270 sx = [[180 - @angle, 45].min, -45].max else sx = [@angle - 360, -45].max end sy = [[(@angle - 180).abs - 90, 45].min, -45].max base = @angle * PI / 180 base + (atan2(sx, sy) - base) * 2 end #-------------------------------------------------------------------------- # ● 画面座標の計算 #-------------------------------------------------------------------------- def display_x (@x - view_distance * sin(angle_radian) + 0.5) % $game_map.width - center_x end def display_y (@y - view_distance * cos(angle_radian) + 0.5) % $game_map.height - center_y end #-------------------------------------------------------------------------- # ● 視界距離の取得 #-------------------------------------------------------------------------- def view_distance 5.8 + (Graphics.height - 416) / 64.0 end #-------------------------------------------------------------------------- # ● スナップ距離の取得 #-------------------------------------------------------------------------- def snap_distance view_distance * 32 - 8 end #-------------------------------------------------------------------------- # ● 画面中央の座標 #-------------------------------------------------------------------------- def center_x Graphics.width / 64.0 end def center_y Graphics.height / 64.0 end #-------------------------------------------------------------------------- # ● スナップ用原点座標の計算 #-------------------------------------------------------------------------- def snap_ox ((@x * 32).to_i - ($game_map.display_x * 32).to_i + 16) % ($game_map.width * 32) end def snap_oy ((@y * 32).to_i - ($game_map.display_y * 32).to_i + 16) % ($game_map.height * 32) end #-------------------------------------------------------------------------- # ● 原点 Y 座標の計算 #-------------------------------------------------------------------------- def adjust_oy(sy) s = (Graphics.height - 416) / 2 rate = sy / (256.0 + s) (adjust_bottom(s) + adjust_height(s) * rate + adjust_alt(rate)).to_i end def adjust_bottom(s) 88 + s end def adjust_height(s) 318 + s - @altitude / 10.0 end def adjust_alt(rate) (190 - @altitude) * (sin((0.75 - 0.5 * rate) * PI) - sin(0.75 * PI)) end #-------------------------------------------------------------------------- # ● 表示座標を差し引いた Y 座標の計算 #-------------------------------------------------------------------------- def adjust_y(sy) 160 + ((sy / 16.0) ** 2).to_i end #-------------------------------------------------------------------------- # ● 拡大率の取得 #-------------------------------------------------------------------------- def adjust_zoom(sy) s = (Graphics.height - 416) / 2 1.333 + 420.0 / (@altitude + 60) * sy / (318 + s) end #-------------------------------------------------------------------------- # ● 乗り物画面表示座標の取得 #-------------------------------------------------------------------------- def vscreen_x Graphics.width / 2 end def vscreen_y Graphics.height - 48 - (flight? ? @altitude * 2 : 0) end def vscreen_z 100 end #-------------------------------------------------------------------------- # ● 乗り物画面表示拡大率の取得 #-------------------------------------------------------------------------- def vscreen_zoom param(:vehicle_zoom) || 2.0 end #-------------------------------------------------------------------------- # ● 原点から Y 座標の計算 #-------------------------------------------------------------------------- STEP = 5 def origin_y(oy) s = (Graphics.height - 416) / 2 b = adjust_bottom(s) h = adjust_height(s) return 0 unless oy.between?(b, b + h + 32) i = ((oy - b - (190 - @altitude) * 0.3) * (256 + s) / h).to_i i += STEP while adjust_oy(i) < oy n1 = adjust_oy(i - STEP) n2 = adjust_oy(i) i += STEP.to_f * (oy - n1) / (n2 - n1) - STEP if n1 < n2 adjust_y(i) end end #============================================================================== # ■ Game_Interpreter #============================================================================== class Game_Interpreter #-------------------------------------------------------------------------- # ☆ 乗り物の乗降 #-------------------------------------------------------------------------- def command_206 if $game_player.in_vehicle && next_event_code == 201 $game_player.keep_vehicle SceneManager.goto(Scene_Map) elsif !$game_player.get_on_off_vehicle $game_player.get_on_keep_vehicle end end end #━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ # # スプライト # #━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ #============================================================================== # ■ Sprite_Character #============================================================================== class Sprite_Character #-------------------------------------------------------------------------- # ○ 解放 #-------------------------------------------------------------------------- alias _wdtk_veh3d_dispose dispose def dispose dispose_shadow _wdtk_veh3d_dispose end #-------------------------------------------------------------------------- # ○ フレーム更新 #-------------------------------------------------------------------------- alias _wdtk_veh3d_update update def update _wdtk_veh3d_update update_shadow end #-------------------------------------------------------------------------- # ● 影表示の開始 #-------------------------------------------------------------------------- def start_shadow @shadow_sprite = ::Sprite.new(viewport) @shadow_sprite.bitmap = Cache.system("Shadow") @shadow_sprite.ox = @shadow_sprite.bitmap.width / 2 @shadow_sprite.oy = @shadow_sprite.bitmap.height @shadow_sprite.z = 180 end #-------------------------------------------------------------------------- # ● 影の解放 #-------------------------------------------------------------------------- def dispose_shadow if @shadow_sprite @shadow_sprite.dispose @shadow_sprite = nil end end #-------------------------------------------------------------------------- # ● 影の更新 #-------------------------------------------------------------------------- def update_shadow return unless @character.is_a?(Game_Vehicle) altitude = @character.altitude altitude -= 10 if $game_player.keep_vehicles.include?(@character.type) if altitude > 0 start_shadow unless @shadow_sprite @shadow_sprite.x = @character.screen_x @shadow_sprite.y = @character.screen_y + altitude @shadow_sprite.opacity = altitude * 8 else dispose_shadow end end end #============================================================================== # ■ Sprite_Vehicle #============================================================================== class Sprite_Vehicle < Sprite_Character #-------------------------------------------------------------------------- # ● 転送元ビットマップの更新 #-------------------------------------------------------------------------- def update_bitmap if graphic_changed? @tile_id = 0 @character_name = @character.character_name @character_index = @character.vehicle_index set_character_bitmap end end #-------------------------------------------------------------------------- # ● グラフィックの変更判定 #-------------------------------------------------------------------------- def graphic_changed? @character_name != @character.character_name || @character_index != @character.vehicle_index end #-------------------------------------------------------------------------- # ● 転送元矩形の更新 #-------------------------------------------------------------------------- def update_src_rect if @tile_id == 0 index = @character_index pattern = @character.pattern < 3 ? @character.pattern : 1 direction = @character.drive_direction direction = 8 if direction == 5 direction += 5 <=> direction if direction.odd? sx = (index % 4 * 3 + pattern) * @cw sy = (index / 4 * 4 + (direction - 2) / 2) * @ch self.src_rect.set(sx, sy, @cw, @ch) end end #-------------------------------------------------------------------------- # ● 位置の更新 #-------------------------------------------------------------------------- def update_position self.x = @character.vscreen_x self.y = @character.vscreen_y self.z = @character.vscreen_z self.zoom_x = self.zoom_y = @character.vscreen_zoom end #-------------------------------------------------------------------------- # ● 新しいエフェクトの設定 #-------------------------------------------------------------------------- def setup_new_effect if !animation? && $game_player.animation_id > 0 animation = $data_animations[$game_player.animation_id] start_animation(animation) end if !@balloon_sprite && $game_player.balloon_id > 0 @balloon_id = $game_player.balloon_id start_balloon end end #-------------------------------------------------------------------------- # ● アニメーションの終了 #-------------------------------------------------------------------------- def end_animation super $game_player.animation_id = 0 end #-------------------------------------------------------------------------- # ● フキダシアイコンの終了 #-------------------------------------------------------------------------- def end_balloon dispose_balloon $game_player.balloon_id = 0 end #-------------------------------------------------------------------------- # ● 影表示の開始 #-------------------------------------------------------------------------- def start_shadow super @shadow_sprite.oy -= 6 end #-------------------------------------------------------------------------- # ● 影の更新 #-------------------------------------------------------------------------- def update_shadow if @character.flight? start_shadow unless @shadow_sprite @shadow_sprite.x = Graphics.width / 2 snap_y = Graphics.height / 2 + @character.snap_distance.to_i @shadow_sprite.y = @character.origin_y(snap_y) @shadow_sprite.z = @character.screen_z - 1 @shadow_sprite.opacity = 255 * (90 - @character.altitude / 2) / 90 @shadow_sprite.zoom_x = (200 - @character.altitude) / 90.0 @shadow_sprite.zoom_y = @shadow_sprite.zoom_x end end end #============================================================================== # ■ Spriteset_Map #============================================================================== class Spriteset_Map #-------------------------------------------------------------------------- # ☆ 飛行船の影スプライトの削除 #-------------------------------------------------------------------------- def create_shadow; end def dispose_shadow; end def update_shadow; end end #============================================================================== # ■ Spriteset_Vehicle #============================================================================== class Spriteset_Vehicle < Spriteset_Map #-------------------------------------------------------------------------- # ● 定数 #-------------------------------------------------------------------------- RATE = 32 CUT = 2 #-------------------------------------------------------------------------- # ● オブジェクト初期化 #-------------------------------------------------------------------------- def initialize(viewport) @veh_viewport0 = Viewport.new @veh_viewport4 = viewport @vehicle = $game_player.vehicle create_snap create_scenery create_ground create_vehicle super() end #-------------------------------------------------------------------------- # ● ビューポートの作成 #-------------------------------------------------------------------------- def create_viewports super @viewport1.z = 9990 end #-------------------------------------------------------------------------- # ● 背景の作成 #-------------------------------------------------------------------------- def create_scenery @scenery = Plane.new#(@veh_viewport0) @scenery.z = -100 end #-------------------------------------------------------------------------- # ● 地面の作成 #-------------------------------------------------------------------------- def create_ground n = 256 + (Graphics.height - 416) / 2 m = 0 y1 = @vehicle.adjust_y(0) @ground_sprites = Array.new(n) do |i| y2 = @vehicle.adjust_y(i + 1) next nil if (y2 - y1) <= [i / RATE, CUT].min y1 = y2 m += 1 sprite = Sprite.new(@veh_viewport0) sprite.x = Graphics.width / 2 sprite.ox = Graphics.width / 2 sprite.opacity = m * 32 sprite end end #-------------------------------------------------------------------------- # ● 乗り物スプライトの作成 #-------------------------------------------------------------------------- def create_vehicle @sprite_vehicle = Sprite_Vehicle.new(@veh_viewport0, @vehicle) end #-------------------------------------------------------------------------- # ● キャラクタースプライトの作成 #-------------------------------------------------------------------------- def create_characters super @character_sprites.reject! do |sprite| case sprite.character when $game_player, Game_Follower, @vehicle sprite.dispose end sprite.disposed? end end #-------------------------------------------------------------------------- # ● 撮影用スプライトの作成 #-------------------------------------------------------------------------- def create_snap @snap_sprite = Sprite.new @snap_sprite.x = Graphics.width / 2 @snap_sprite.y = Graphics.height / 2 + @vehicle.snap_distance @snap_sprite.z = 9999 end #-------------------------------------------------------------------------- # ● 解放 #-------------------------------------------------------------------------- def dispose super dispose_snap dispose_scenery dispose_ground dispose_vehicle end #-------------------------------------------------------------------------- # ● ビューポートの解放 #-------------------------------------------------------------------------- def dispose_viewports @veh_viewport0.dispose super end #-------------------------------------------------------------------------- # ● 撮影用スプライトの解放 #-------------------------------------------------------------------------- def dispose_snap @snap_sprite.dispose end #-------------------------------------------------------------------------- # ● 背景の解放 #-------------------------------------------------------------------------- def dispose_scenery @scenery.bitmap.dispose if @scenery.bitmap && !@scenery.bitmap.disposed? @scenery.dispose end #-------------------------------------------------------------------------- # ● 地面の解放 #-------------------------------------------------------------------------- def dispose_ground @ground_sprites.each {|sprite| sprite.dispose if sprite } end #-------------------------------------------------------------------------- # ● 乗り物スプライトの解放 #-------------------------------------------------------------------------- def dispose_vehicle @sprite_vehicle.dispose end #-------------------------------------------------------------------------- # ● フレーム更新 #-------------------------------------------------------------------------- def update super return unless WdTk::Veh3D.need_update? last_brightness = Graphics.brightness Graphics.brightness = 255 on_snap update_snap on_ground update_scenery update_ground update_vehicle on_base Graphics.brightness = last_brightness end #-------------------------------------------------------------------------- # ● タイルマップの更新 #-------------------------------------------------------------------------- def update_tilemap $game_map.set_pos(@vehicle.display_x, @vehicle.display_y) super end #-------------------------------------------------------------------------- # ● 天候の更新 #-------------------------------------------------------------------------- def update_weather super @weather.ox = -@vehicle.angle @weather.oy = 0 end #-------------------------------------------------------------------------- # ● スナップの撮影 #-------------------------------------------------------------------------- def on_snap @viewport1.visible = true @veh_viewport0.visible = @viewport2.visible = @viewport3.visible = @veh_viewport4.visible = false @scenery.visible = false @snap_sprite.bitmap.dispose if @snap_sprite.bitmap @snap_sprite.bitmap = Graphics.snap_to_bitmap end #-------------------------------------------------------------------------- # ● スナップの更新 #-------------------------------------------------------------------------- def update_snap gh = Graphics.height gx = (Graphics.width - gh) / 2 @snap_sprite.ox = @vehicle.snap_ox - gx @snap_sprite.oy = @vehicle.snap_oy @snap_sprite.src_rect.set(gx, 0, gh, gh) @snap_sprite.angle = -@vehicle.angle end #-------------------------------------------------------------------------- # ● 背景の更新 #-------------------------------------------------------------------------- def update_scenery if WdTk::Veh3D::Scenery @scenery.bitmap = Cache.parallax(WdTk::Veh3D::Scenery) else @scenery.bitmap = @parallax.bitmap end angle = -@vehicle.angle * WdTk::Veh3D::Repeat % 360 @scenery.ox = @scenery.bitmap.width * angle / 360 end #-------------------------------------------------------------------------- # ● 地面の撮影 #-------------------------------------------------------------------------- def on_ground @viewport1.visible = false @veh_viewport0.visible = @viewport2.visible = @viewport3.visible = @veh_viewport4.visible = false @snap_sprite.visible = true @scenery.visible = true @scenery.oy = 160 - 64 @bitmap.dispose if @bitmap @bitmap = Graphics.snap_to_bitmap end #-------------------------------------------------------------------------- # ● 地面の更新 #-------------------------------------------------------------------------- def update_ground next_y = @vehicle.adjust_y(0) last_oy = @vehicle.adjust_oy(0) @ground_sprites.each_with_index do |sprite, i| next unless sprite sprite.bitmap = @bitmap next_oy = @vehicle.adjust_oy(i + 1) height = (next_oy > last_oy ? next_oy - last_oy : 1) sprite.src_rect.set(0, last_oy, @bitmap.width, height) last_oy = next_oy sprite.y = next_y sprite.zoom_x = @vehicle.adjust_zoom(sprite.y - 160) next_y = @vehicle.adjust_y(i + 1) sprite.zoom_y = (next_y - sprite.y).to_f / height end end #-------------------------------------------------------------------------- # ● 乗り物の更新 #-------------------------------------------------------------------------- def update_vehicle @sprite_vehicle.update end #-------------------------------------------------------------------------- # ● 基本状態に戻す #-------------------------------------------------------------------------- def on_base @snap_sprite.visible = false @veh_viewport0.visible = @viewport2.visible = @viewport3.visible = @veh_viewport4.visible = true @scenery.oy = 0 end end #━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ # # ウィンドウ # #━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ #============================================================================== # ■ Window_Message #============================================================================== class Window_Message #-------------------------------------------------------------------------- # ● ビューポートの設定 #-------------------------------------------------------------------------- def viewport=(viewport) super @back_sprite.viewport = viewport @gold_window.viewport = viewport @choice_window.viewport = viewport @number_window.viewport = viewport @item_window.viewport = viewport end end #━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ # # シーン # #━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ #============================================================================== # ■ Scene_Map #============================================================================== class Scene_Map < Scene_Base #-------------------------------------------------------------------------- # ◯ 終了前処理 #-------------------------------------------------------------------------- alias _wdtk_veh3d_pre_terminate pre_terminate def pre_terminate _wdtk_veh3d_pre_terminate fadeout(30) if SceneManager.scene_is?(Scene_Vehicle) end end #============================================================================== # ■ Scene_Vehicle #------------------------------------------------------------------------------ #  乗り物画面の処理を行うクラスです。 #============================================================================== class Scene_Vehicle < Scene_Map #-------------------------------------------------------------------------- # ● 開始処理 #-------------------------------------------------------------------------- def start WdTk::Veh3D.reset $game_player.on_vehicle_start super end #-------------------------------------------------------------------------- # ● 終了前処理 #-------------------------------------------------------------------------- def pre_terminate super pre_map_scene if SceneManager.scene_is?(Scene_Map) end #-------------------------------------------------------------------------- # ● 終了処理 #-------------------------------------------------------------------------- def terminate $game_player.on_vehicle_end if SceneManager.scene_is?(Scene_Map) super GC.start end #-------------------------------------------------------------------------- # ● ビューポートの作成 #-------------------------------------------------------------------------- def create_main_viewport super @window_viewport = Viewport.new @window_viewport.z = 200 end #-------------------------------------------------------------------------- # ● ビューポートの解放 #-------------------------------------------------------------------------- def dispose_main_viewport super @window_viewport.dispose end #-------------------------------------------------------------------------- # ● フレーム更新(基本) #-------------------------------------------------------------------------- def update_basic if WdTk::Veh3D.need_update? Graphics.frame_rate = WdTk::Veh3D::FrameRate Graphics.update Graphics.frame_rate = 60 else Graphics.frame_count += 1 end Input.update WdTk::Veh3D.update update_all_windows end #-------------------------------------------------------------------------- # ● 汎用フェード処理 #-------------------------------------------------------------------------- def fade_loop(duration) WdTk::Veh3D.reset super Graphics.frame_reset end #-------------------------------------------------------------------------- # ● スプライトセットの作成 #-------------------------------------------------------------------------- def create_spriteset @spriteset = Spriteset_Vehicle.new(@window_viewport) end #-------------------------------------------------------------------------- # ● メッセージウィンドウの作成 #-------------------------------------------------------------------------- def create_message_window super @message_window.viewport = @window_viewport end #-------------------------------------------------------------------------- # ● スクロール文章ウィンドウの作成 #-------------------------------------------------------------------------- def create_scroll_text_window super @scroll_text_window.viewport = @window_viewport end #-------------------------------------------------------------------------- # ● マップ名ウィンドウの作成 #-------------------------------------------------------------------------- def create_location_window super @map_name_window.viewport = @window_viewport end #-------------------------------------------------------------------------- # ● キャンセルボタンによるメニュー呼び出し判定 #-------------------------------------------------------------------------- def update_call_menu end #-------------------------------------------------------------------------- # ● マップ画面遷移の前処理 #-------------------------------------------------------------------------- def pre_map_scene fadeout(30) Graphics.brightness = 0 end end #============================================================================== # ■ Scene_Base #============================================================================== class Scene_Base #-------------------------------------------------------------------------- # ○ メイン処理 #-------------------------------------------------------------------------- alias _wdtk_veh3d_main main def main _wdtk_veh3d_main if SceneManager.scene_is?(Scene_Map) and $game_player.in_vehicle SceneManager.goto(Scene_Vehicle) end end end