=begin ▼ 乗り物擬似3D化 for VX ゲームデータ ver. 1.1.0 RPGツクールVX用スクリプト 制作 : 木星ペンギン URL : http://woodpenguin.blog.fc2.com/ =end #////////////////////////////////////////////////////////////////////////////// # # 設定項目なし # #////////////////////////////////////////////////////////////////////////////// #////////////////////////////////////////////////////////////////////////////// # # ゲームオブジェクト # #////////////////////////////////////////////////////////////////////////////// #============================================================================== # ■ Game_System #============================================================================== class Game_System #-------------------------------------------------------------------------- # ☆ タイマーの設定 #-------------------------------------------------------------------------- def timer=(timer) @timer = timer * 60 / Graphics.frame_rate end #-------------------------------------------------------------------------- # ☆ フレーム更新 #-------------------------------------------------------------------------- def update if @timer_working and @timer > 0 @timer -= 60 / Graphics.frame_rate @timer = 0 if @timer < 0 if @timer == 0 and $game_temp.in_battle # 戦闘中にタイマーが 0 に $game_temp.next_scene = "map" # なったら戦闘を中断する end end end end #============================================================================== # ■ Game_Map #============================================================================== class Game_Map #-------------------------------------------------------------------------- # ◯ 乗り物の作成 #-------------------------------------------------------------------------- alias _wdtk_veh3d_create_vehicles create_vehicles def create_vehicles _wdtk_veh3d_create_vehicles for i in 3...WdTk::Veh3D.data.size @vehicles[i] = Game_Vehicle.new(3) end end #-------------------------------------------------------------------------- # ● 表示位置の設定 (ループ判定なし) #-------------------------------------------------------------------------- def set_pos(x, y) @display_x = x @display_y = y @parallax_x = x @parallax_y = y end #-------------------------------------------------------------------------- # ● 指定座標にあるオートタイルの種類を取得 #-------------------------------------------------------------------------- def autotile_type(x, y, z) @map.data[x, y, z] >= 2048 ? (@map.data[x, y, z] - 2048) / 48 : -1 end #-------------------------------------------------------------------------- # ● 乗り物の通行可能判定 #-------------------------------------------------------------------------- def vehicle_passable?(x, y, types, through) return true unless types for event in events_xy(x, y) # 座標が一致するイベントを調べる tile_id = event.tile_id if tile_id >= 2048 return types.include?((tile_id - 2048) / 48) elsif tile_id > 0 flag = @passages[tile_id] next if flag & 0x10 != 0 return (through && flag & 0x01 == 0) end end for i in [2, 1, 0] # レイヤーの上から順に調べる tile_id = @map.data[x, y, i] if tile_id >= 2048 return types.include?((tile_id - 2048) / 48) else flag = @passages[tile_id] next if flag & 0x10 != 0 return (through && flag & 0x01 == 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 passable?(x, y, 0x01) end #-------------------------------------------------------------------------- # ● ループ補正後の X 実座標計算 # real_x : X 実座標 #-------------------------------------------------------------------------- def round_real_x(real_x) if loop_horizontal? return (real_x + width * 256) % (width * 256) else return real_x end end #-------------------------------------------------------------------------- # ● ループ補正後の Y 実座標計算 # real_y : Y 実座標 #-------------------------------------------------------------------------- def round_real_y(real_y) if loop_vertical? return (real_y + height * 256) % (height * 256) else return real_y end end end #============================================================================== # ■ Game_Character #============================================================================== class Game_Character #-------------------------------------------------------------------------- # ☆ キャラクター衝突判定 # x : X 座標 # y : Y 座標 # プレイヤーと乗り物を含め、通常キャラの衝突を検出する。 #-------------------------------------------------------------------------- def collide_with_characters?(x, y) for event in $game_map.events_xy(x, y) # イベントの座標と一致 unless event.through # すり抜け OFF? return true if self.is_a?(Game_Event) # 自分がイベント return true if event.priority_type == 1 # 相手が通常キャラ end end if @priority_type == 1 # 自分が通常キャラ return true if $game_player.pos_nt?(x, y) # プレイヤーの座標と一致 for vehicle in $game_map.vehicles return true if vehicle.pos_nt?(x, y) && !vehicle.get_here? end end return false end end #============================================================================== # ■ Game_Player #============================================================================== class Game_Player #-------------------------------------------------------------------------- # ● 公開インスタンス変数 #-------------------------------------------------------------------------- attr_accessor :in_vehicle #-------------------------------------------------------------------------- # ◯ 場所移動の実行 #-------------------------------------------------------------------------- alias _wooden_veh3d_perform_transfer perform_transfer def perform_transfer vehicle.set_direction(@new_direction) if @transferring && in_vehicle? _wooden_veh3d_perform_transfer end #-------------------------------------------------------------------------- # ● 現在乗っている乗り物を取得 #-------------------------------------------------------------------------- def vehicle $game_map.vehicles[@vehicle_type] end #-------------------------------------------------------------------------- # ☆ 飛行する乗り物に乗っているかどうか #-------------------------------------------------------------------------- def in_airship? in_vehicle? && vehicle.flight? end #-------------------------------------------------------------------------- # ☆ 移動可能判定 #-------------------------------------------------------------------------- def movable? return false if moving? # 移動中 return false if @move_route_forcing # 移動ルート強制中 return false if @vehicle_getting_on # 乗る動作の途中 return false if @vehicle_getting_off # 降りる動作の途中 return false if $game_message.visible # メッセージ表示中 return false if in_vehicle? and not vehicle.movable? return true end #-------------------------------------------------------------------------- # ◯ フレーム更新 #-------------------------------------------------------------------------- alias _wooden_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 = vehicle.x @y = vehicle.y @real_x = @x * 256 @real_y = @y * 256 update_vehicle_moving(last_x != @x || last_y != @y) else _wooden_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 return unless in_vehicle? vehicle = $game_map.vehicles[@vehicle_type] if @vehicle_getting_on # 乗る途中? if not moving? @vehicle_getting_on = false # 乗る動作終了 @transparent = true # 透明化 vehicle.get_on end elsif @vehicle_getting_off # 降りる途中? if not moving? and vehicle.altitude == 0 @vehicle_getting_off = false # 降りる動作終了 @vehicle_type = -1 # 乗り物タイプ消去 @transparent = false # 透明を解除 end else # 乗り物に乗っている vehicle.sync_with_player # プレイヤーと同時に動かす end end #-------------------------------------------------------------------------- # ◯ エンカウントの更新 #-------------------------------------------------------------------------- alias _wooden_veh3d_update_encounter update_encounter def update_encounter if in_vehicle? return if $TEST and Input.press?(Input::CTRL) # テストプレイ中? @encounter_count -= vehicle.encount_rate / 100.0 else _wooden_veh3d_update_encounter end end #-------------------------------------------------------------------------- # ☆ 乗り物に乗る # 現在乗り物に乗っていないことが前提。 #-------------------------------------------------------------------------- def get_on_vehicle front_x = $game_map.x_with_direction(@x, @direction) front_y = $game_map.y_with_direction(@y, @direction) for i in 0...$game_map.vehicles.size veh = $game_map.vehicles[i] if veh.get_here? @vehicle_type = i if veh.pos?(@x, @y) else @vehicle_type = i if veh.pos?(front_x, front_y) end end if in_vehicle? @vehicle_getting_on = true force_move_forward unless vehicle.get_here? @walking_bgm = RPG::BGM::last # 歩行時の BGM 記憶 return true end return false end #-------------------------------------------------------------------------- # ☆ 乗り物から降りる #-------------------------------------------------------------------------- def get_off_vehicle return unless vehicle.land_ok?(@x, @y, vehicle.angle_dir) vehicle.get_off set_direction(vehicle.sync_dir? ? vehicle.angle_dir : 2) @vehicle_getting_off = true # 降りる動作の開始 @move_speed = 4 # 移動速度を戻す @through = false # すり抜け OFF @walking_bgm.play # 歩行時の BGM 復帰 make_encounter_count # エンカウント初期化 end #-------------------------------------------------------------------------- # ● 乗り物開始処理 #-------------------------------------------------------------------------- def on_vehicle_start @in_vehicle = true vehicle.on_vehicle_start end #-------------------------------------------------------------------------- # ● 乗り物終了処理 #-------------------------------------------------------------------------- def on_vehicle_end @in_vehicle = false center(@x, @y) vehicle.on_vehicle_end unless vehicle.get_here? force_move_forward @transparent = false end end end #============================================================================== # ■ Game_Vehicle #============================================================================== class Game_Vehicle #-------------------------------------------------------------------------- # ● モジュール #-------------------------------------------------------------------------- include Math #-------------------------------------------------------------------------- # ● 公開インスタンス変数 #-------------------------------------------------------------------------- attr_reader :angle attr_reader :drive_direction attr_accessor :altitude attr_accessor :control #-------------------------------------------------------------------------- # ◯ オブジェクト初期化 #-------------------------------------------------------------------------- alias _wooden_veh3d_initialize initialize def initialize(type) _wooden_veh3d_initialize(type) @drive_speed = 0 @drive_direction = 5 @angle = 0 @angle_speed = 0 @control = false end #-------------------------------------------------------------------------- # ● 乗り物データの取得 #-------------------------------------------------------------------------- def param(sym) WdTk::Veh3D.data[@type][sym] end #-------------------------------------------------------------------------- # ☆ システム設定のロード #-------------------------------------------------------------------------- def load_system_settings case @type when 0; sys_vehicle = $data_system.boat when 1; sys_vehicle = $data_system.ship when 2; sys_vehicle = $data_system.airship else; sys_vehicle = param(:system) end if sys_vehicle != nil @character_name = sys_vehicle.character_name @character_index = sys_vehicle.character_index @bgm = sys_vehicle.bgm @map_id = sys_vehicle.start_map_id @x = sys_vehicle.start_x @y = sys_vehicle.start_y end end #-------------------------------------------------------------------------- # ● 移動中判定 #-------------------------------------------------------------------------- def moving? @control ? (@drive_speed != 0 or @angle_speed != 0) : super end #-------------------------------------------------------------------------- # ● デバッグすり抜け状態判定 #-------------------------------------------------------------------------- def debug_through? $TEST && Input.press?(:CTRL) end #-------------------------------------------------------------------------- # ● イベントとの衝突判定 #-------------------------------------------------------------------------- def collide_with_events?(x, y) $game_map.events_xy(x, y).any? do |event| not event.through and event.priority_type == 1 end end #-------------------------------------------------------------------------- # ● 乗り物との衝突判定 #-------------------------------------------------------------------------- def collide_with_vehicles?(x, y) $game_map.vehicles.any? {|v| v != self and v.pos_nt?(x, y) } end #-------------------------------------------------------------------------- # ● 指定方向に向き変更 # d : 方向(2,4,6,8) #-------------------------------------------------------------------------- def set_direction(d) super if @driving and 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_name case @drive_direction when 5; param(:vehicle_name1) or @character_name when 2,4,6,8; param(:vehicle_name2) or param(:vehicle_name1) or @character_name when 1,3,7,9; param(:vehicle_name3) or @character_name end end def vehicle_index case @drive_direction when 5; param(:vehicle_index1) or @character_index when 2,4,6,8; param(:vehicle_index2) or param(:vehicle_index1) or @character_index when 1,3,7,9; param(:vehicle_index3) or @character_index end 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 @move_speed = param(:move_speed) if @driving @drive_direction = 5 @walk_anime = param(:walk_anime) != false @step_anime = param(:step_anime) != false else @walk_anime = @step_anime = false end end #-------------------------------------------------------------------------- # ◯ 乗り物に乗る #-------------------------------------------------------------------------- alias _wooden_veh3d_get_on get_on def get_on _wooden_veh3d_get_on @walk_anime = param(:walk_anime) != false @step_anime = param(:step_anime) != false if flight? @priority_type = 2 # プライオリティを「通常キャラの上」に変更 end @drive_speed = 0 @drive_direction = 5 @angle = 0 set_direction($game_player.direction) if sync_dir? @angle_speed = 0 $game_temp.next_scene = "vehicle" end #-------------------------------------------------------------------------- # ◯ 乗り物から降りる #-------------------------------------------------------------------------- alias _wooden_veh3d_get_off get_off def get_off _wooden_veh3d_get_off $game_temp.next_scene = "map" end #-------------------------------------------------------------------------- # ● 乗り物開始処理 #-------------------------------------------------------------------------- def on_vehicle_start unless @control @control = true if flight? @altitude = [[@altitude, max_altitude].min, min_altitude].max else @altitude = 10 end $game_switches[param(:switch_id)] = true if param(:switch_id) end end #-------------------------------------------------------------------------- # ● 乗り物終了処理 #-------------------------------------------------------------------------- def on_vehicle_end unless @driving @control = false @altitude = flight? ? 32 : 0 moveto((@real_x + 128) / 256, (@real_y + 128) / 256) $game_switches[param(:switch_id)] = false if param(:switch_id) end end #-------------------------------------------------------------------------- # ● 停止 #-------------------------------------------------------------------------- def stop @drive_speed = 0 @angle_speed = 0 @stop_count = 0 end #-------------------------------------------------------------------------- # ● 移動可能判定 #-------------------------------------------------------------------------- def movable? @driving 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) or 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 #-------------------------------------------------------------------------- # ◯ フレーム更新 #-------------------------------------------------------------------------- alias _wooden_veg3d_update update def update if @control if not @driving and @altitude > 20 if @altitude <= 40 @altitude -= 1 else @altitude -= 2 end end else _wooden_veg3d_update end end #-------------------------------------------------------------------------- # ● ボタンが押されているかどうか #-------------------------------------------------------------------------- def key_press?(sym) sym != nil and Input.press?(Input.const_get(sym)) end #-------------------------------------------------------------------------- # ● 乗り物操縦時の処理 #-------------------------------------------------------------------------- def process_control update_animation @drive_direction = 5 if key_press?(param(:inp_forward1)) or key_press?(param(:inp_forward2)) process_forward elsif key_press?(param(:inp_backward)) process_backward else process_reduce_drive end unless key_press?(param(:inp_horz)) if key_press?(param(:inp_turnleft)) process_turnleft elsif key_press?(param(:inp_turnright)) process_turnright else process_reduce_turn end if flight? process_up if key_press?(param(:inp_up)) process_down if key_press?(param(:inp_down)) end else process_reduce_turn end update_angle if @drive_speed != 0 update_drive(@angle, 2 ** @move_speed * @drive_speed / 12) elsif key_press?(param(:inp_horz)) process_horz end if moving? if @walk_anime @anime_count += 1.5 elsif @step_anime @anime_count += 1 end else update_stop end end #-------------------------------------------------------------------------- # ● 操縦以外の処理 #-------------------------------------------------------------------------- def process_handling if @drive_speed <= 12 if key_press?(param(:inp_get_off)) return stop if $game_player.get_off_vehicle end if key_press?(param(:inp_event)) $game_player.set_direction(angle_dir) return stop if $game_player.check_action_event end end if key_press?(param(:inp_menu)) return process_menu end end #-------------------------------------------------------------------------- # ● 前進の処理 #-------------------------------------------------------------------------- def process_forward @drive_speed += 1 if @drive_speed < 16 @stop_count = 0 end #-------------------------------------------------------------------------- # ● 後退の処理 #-------------------------------------------------------------------------- def process_backward @drive_speed -= 1 if @drive_speed > -8 @stop_count = 0 end #-------------------------------------------------------------------------- # ● 速度低下の処理 #-------------------------------------------------------------------------- def process_reduce_drive @drive_speed += (0 <=> @drive_speed) end #-------------------------------------------------------------------------- # ● 左旋回の処理 #-------------------------------------------------------------------------- def process_turnleft @angle_speed += 1 if @angle_speed < param(:turning) @drive_direction -= 1 if @angle_speed > 0 && param(:dir_type) >= 1 @stop_count = 0 end #-------------------------------------------------------------------------- # ● 右旋回の処理 #-------------------------------------------------------------------------- def process_turnright @angle_speed -= 1 if @angle_speed > -param(:turning) @drive_direction += 1 if @angle_speed < 0 && param(:dir_type) >= 1 @stop_count = 0 end #-------------------------------------------------------------------------- # ● 旋回低下の処理 #-------------------------------------------------------------------------- def process_reduce_turn @angle_speed += (0 <=> @angle_speed) end #-------------------------------------------------------------------------- # ● 上昇の処理 #-------------------------------------------------------------------------- def process_up @altitude += 2 if @altitude < max_altitude @drive_direction += 3 if param(:dir_type) >= 2 end #-------------------------------------------------------------------------- # ● 下降の処理 #-------------------------------------------------------------------------- def process_down @altitude -= 2 if @altitude > min_altitude @drive_direction -= 3 if param(:dir_type) >= 2 end #-------------------------------------------------------------------------- # ● メニュー呼び出しの処理 #-------------------------------------------------------------------------- def process_menu $game_temp.menu_beep = true $game_temp.next_scene = "menu" 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, 2 ** @move_speed * 4 / 12) end #-------------------------------------------------------------------------- # ● 向きの更新 #-------------------------------------------------------------------------- def update_angle @angle = (@angle + @angle_speed / 4.0) % 360 end #-------------------------------------------------------------------------- # ● 移動時の更新 #-------------------------------------------------------------------------- def update_drive(angle, distance) x1 = $game_map.round_x((@real_x + 128) / 256) y1 = $game_map.round_y((@real_y + 128) / 256) tx = $game_map.round_real_x(@real_x - (sin(angle * PI / 180) * distance).to_i) ty = $game_map.round_real_y(@real_y - (cos(angle * PI / 180) * distance).to_i) x2 = round_x_with_pos(tx) y2 = round_y_with_pos(ty) if x1 == x2 or vehicle_passable?(x2, y1) @real_x = tx @x = $game_map.round_x((@real_x + 128) / 256) if (y1 == y2 or vehicle_passable?(x1, y2)) and (x1 == x2 or vehicle_passable?(x2, y2)) @real_y = ty @y = $game_map.round_y((@real_y + 128) / 256) end elsif y1 == y2 or vehicle_passable?(x1, y2) @real_y = ty @y = $game_map.round_y((@real_y + 128) / 256) end end #-------------------------------------------------------------------------- # ☆ 飛行船の最大高度を取得 #-------------------------------------------------------------------------- def max_altitude param(:max_altitude) or 100 end #-------------------------------------------------------------------------- # ● 飛行船の最低高度を取得 #-------------------------------------------------------------------------- def min_altitude param(:min_altitude) or 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_characters?(x, y) else x2 = $game_map.x_with_direction(x, d) y2 = $game_map.y_with_direction(y, d) return false unless $game_map.valid?(x2, y2) return false unless $game_map.passable?(x2, y2) 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 or debug_through? return false unless map_passable?(x2, y2) if not flight? and collide_with_events?(x2, y2) stop if $game_player.check_event_trigger_touch(x2, y2) return false end return false if not flight? and collide_with_vehicles?(x2, y2) return true end #-------------------------------------------------------------------------- # ● 特定の方向にずらした座標の計算(ループ補正あり) #-------------------------------------------------------------------------- def round_x_with_pos(real_x) if real_x < @x * 256 return $game_map.round_x(real_x / 256) if real_x % 256 < 128 elsif real_x > @x * 256 return $game_map.round_x((real_x + 255) / 256) if real_x % 256 > 128 end return $game_map.round_x((real_x + 128) / 256) end def round_y_with_pos(real_y) if real_y < @y * 256 return $game_map.round_y(real_y / 256) if real_y % 256 < 128 elsif real_y > @y * 256 return $game_map.round_y((real_y + 255) / 256) if real_y % 256 > 128 end return $game_map.round_y((real_y + 128) / 256) end #-------------------------------------------------------------------------- # ● 乗り物のマップ通行可能判定 #-------------------------------------------------------------------------- def map_passable?(x, y) $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 atan2(sx, sy) end #-------------------------------------------------------------------------- # ● 画面座標の計算 #-------------------------------------------------------------------------- def display_x x = @real_x - (view_distance * sin(angle_radian)).to_i + 128 return x % ($game_map.width * 256) - center_x end def display_y y = @real_y - (view_distance * cos(angle_radian)).to_i + 128 return y % ($game_map.height * 256) - center_y end #-------------------------------------------------------------------------- # ● 視界距離の取得 #-------------------------------------------------------------------------- def view_distance return 1472 end #-------------------------------------------------------------------------- # ● 画面中央の座標 #-------------------------------------------------------------------------- def center_x Graphics.width * 256 / 64 end def center_y Graphics.height * 256 / 64 end #-------------------------------------------------------------------------- # ● スナップ用原点座標の計算 #-------------------------------------------------------------------------- def snap_ox (@real_x - $game_map.display_x + 128) % ($game_map.width * 256) / 8 end def snap_oy (@real_y - $game_map.display_y + 128) % ($game_map.height * 256) / 8 end #-------------------------------------------------------------------------- # ● 原点 Y 座標の計算 #-------------------------------------------------------------------------- def adjust_oy(sy) 96 + 308 * sy / 256 + (74 - @altitude / 2) * (128 ** 2 - (sy - 128) ** 2) / 128 ** 2 end #-------------------------------------------------------------------------- # ● 表示座標を差し引いた Y 座標の計算 #-------------------------------------------------------------------------- def adjust_y(sy) 160 + ((sy / 16.0) ** 2).to_i end #-------------------------------------------------------------------------- # ● 拡大率の取得 #-------------------------------------------------------------------------- def adjust_zoom(sy) 1.3 + 26 / sqrt(@altitude) * sy / 308 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) or 2.0 end end #////////////////////////////////////////////////////////////////////////////// # # スプライト # #////////////////////////////////////////////////////////////////////////////// #============================================================================== # ■ Sprite_Base #============================================================================== class Sprite_Base #-------------------------------------------------------------------------- # ☆ フレーム更新 #-------------------------------------------------------------------------- def update super (60 / Graphics.frame_rate).times do if @animation != nil @animation_duration -= 1 if @animation_duration % 4 == 0 update_animation end end end @@animations.clear end end #============================================================================== # ■ Sprite_Timer #============================================================================== class Sprite_Timer < Sprite #-------------------------------------------------------------------------- # ☆ フレーム更新 #-------------------------------------------------------------------------- def update super self.visible = $game_system.timer_working if $game_system.timer / 60 != @total_sec self.bitmap.clear @total_sec = $game_system.timer / 60 min = @total_sec / 60 sec = @total_sec % 60 text = sprintf("%02d:%02d", min, sec) self.bitmap.font.color.set(255, 255, 255) self.bitmap.draw_text(self.bitmap.rect, text, 1) end end end #============================================================================== # ■ Sprite_Vehicle #============================================================================== class Sprite_Vehicle < Sprite_Base #-------------------------------------------------------------------------- # ● 定数 #-------------------------------------------------------------------------- BALLOON_WAIT = 6 # フキダシ最終フレームのウェイト時間 #-------------------------------------------------------------------------- # ● 公開インスタンス変数 #-------------------------------------------------------------------------- attr_accessor :character #-------------------------------------------------------------------------- # ● オブジェクト初期化 # viewport : ビューポート # character : キャラクター (Game_Character) #-------------------------------------------------------------------------- def initialize(viewport, character = nil) super(viewport) @character = character @balloon_duration = 0 update end #-------------------------------------------------------------------------- # ● 解放 #-------------------------------------------------------------------------- def dispose dispose_balloon super end #-------------------------------------------------------------------------- # ● フレーム更新 #-------------------------------------------------------------------------- def update super update_bitmap self.visible = (not @character.transparent) update_src_rect self.x = @character.vscreen_x self.y = @character.vscreen_y self.z = @character.vscreen_z self.zoom_x = self.zoom_y = @character.vscreen_zoom self.opacity = @character.opacity self.blend_type = @character.blend_type self.bush_depth = @character.bush_depth update_balloon if $game_player.animation_id != 0 animation = $data_animations[$game_player.animation_id] start_animation(animation) $game_player.animation_id = 0 end if $game_player.balloon_id != 0 @balloon_id = $game_player.balloon_id start_balloon $game_player.balloon_id = 0 end end #-------------------------------------------------------------------------- # ● 転送元ビットマップの更新 #-------------------------------------------------------------------------- def update_bitmap if @character_name != @character.vehicle_name or @character_index != @character.vehicle_index @tile_id = 0 @character_name = @character.vehicle_name @character_index = @character.vehicle_index self.bitmap = Cache.character(@character_name) sign = @character_name[/^[\!\$]./] if sign != nil and sign.include?('$') @cw = bitmap.width / 3 @ch = bitmap.height / 4 else @cw = bitmap.width / 12 @ch = bitmap.height / 8 end self.ox = @cw / 2 self.oy = @ch end 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 % 2 == 1 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 start_balloon dispose_balloon @balloon_duration = 4 * 8 + BALLOON_WAIT @balloon_sprite = ::Sprite.new(viewport) @balloon_sprite.bitmap = Cache.system("Balloon") @balloon_sprite.ox = 16 @balloon_sprite.oy = 32 update_balloon end #-------------------------------------------------------------------------- # ● フキダシアイコンの更新 #-------------------------------------------------------------------------- def update_balloon if @balloon_duration > 0 @balloon_duration -= 1 if @balloon_duration == 0 dispose_balloon else @balloon_sprite.x = x @balloon_sprite.y = y - height @balloon_sprite.z = z + 200 if @balloon_duration < BALLOON_WAIT sx = 7 * 32 else sx = (7 - (@balloon_duration - BALLOON_WAIT) / 4) * 32 end sy = (@balloon_id - 1) * 32 @balloon_sprite.src_rect.set(sx, sy, 32, 32) end end end #-------------------------------------------------------------------------- # ● フキダシアイコンの解放 #-------------------------------------------------------------------------- def dispose_balloon if @balloon_sprite != nil @balloon_sprite.dispose @balloon_sprite = nil end end end #============================================================================== # ■ Spriteset_Vehicle #============================================================================== class Spriteset_Vehicle < Spriteset_Map #-------------------------------------------------------------------------- # ● 定数 #-------------------------------------------------------------------------- CUT = 4 #-------------------------------------------------------------------------- # ● オブジェクト初期化 #-------------------------------------------------------------------------- def initialize(viewport) @viewport0 = Viewport.new(0, 0, Graphics.width, Graphics.height) @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(@viewport0) @scenery.z = -100 end #-------------------------------------------------------------------------- # ● 地面の作成 #-------------------------------------------------------------------------- def create_ground @ground_sprites = Array.new((256 + CUT - 1) / CUT) do |i| sprite = Sprite.new(@viewport0) sprite.x = Graphics.width / 2 sprite.ox = Graphics.width / 2 sprite.opacity = i * CUT * 4 sprite end end #-------------------------------------------------------------------------- # ● 乗り物スプライトの作成 #-------------------------------------------------------------------------- def create_vehicle @sprite_vehicle = Sprite_Vehicle.new(@viewport0, @vehicle) end #-------------------------------------------------------------------------- # ● キャラクタースプライトの作成 #-------------------------------------------------------------------------- def create_characters @character_sprites = [] for i in $game_map.events.keys.sort sprite = Sprite_Character.new(@viewport1, $game_map.events[i]) @character_sprites.push(sprite) end for vehicle in $game_map.vehicles if vehicle != @vehicle sprite = Sprite_Character.new(@viewport1, vehicle) @character_sprites.push(sprite) end end end #-------------------------------------------------------------------------- # ● 飛行船の影スプライトの作成 #-------------------------------------------------------------------------- def create_shadow if @vehicle.flight? super @shadow_sprite.viewport = @viewport0 end end #-------------------------------------------------------------------------- # ● 撮影用スプライトの作成 #-------------------------------------------------------------------------- def create_snap @snap_sprite = Sprite.new @snap_sprite.x = Graphics.width / 2 @snap_sprite.y = Graphics.height / 2 + 184 @snap_sprite.z = 9999 end #-------------------------------------------------------------------------- # ● 解放 #-------------------------------------------------------------------------- def dispose super dispose_snap dispose_scenery dispose_ground dispose_vehicle end #-------------------------------------------------------------------------- # ● 飛行船の影スプライトの解放 #-------------------------------------------------------------------------- def dispose_shadow super if @shadow_sprite end #-------------------------------------------------------------------------- # ● ビューポートの解放 #-------------------------------------------------------------------------- def dispose_viewports @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 } end #-------------------------------------------------------------------------- # ● 乗り物スプライトの解放 #-------------------------------------------------------------------------- def dispose_vehicle @sprite_vehicle.dispose end #-------------------------------------------------------------------------- # ● フレーム更新 #-------------------------------------------------------------------------- def update super @viewport1.visible = true @viewport0.visible = @viewport2.visible = @viewport3.visible = @viewport4.visible = false update_snap @viewport1.visible = false @snap_sprite.visible = true update_scenery update_ground update_vehicle @snap_sprite.visible = false @viewport0.visible = @viewport2.visible = @viewport3.visible = @viewport4.visible = true end #-------------------------------------------------------------------------- # ● タイルマップの更新 #-------------------------------------------------------------------------- def update_tilemap $game_map.set_pos(@vehicle.display_x, @vehicle.display_y) super @tilemap.update end #-------------------------------------------------------------------------- # ● キャラクタースプライトの更新 #-------------------------------------------------------------------------- def update_characters super super end #-------------------------------------------------------------------------- # ● 天候の更新 #-------------------------------------------------------------------------- def update_weather @weather.type = $game_map.screen.weather_type @weather.max = $game_map.screen.weather_max @weather.ox = -@vehicle.angle @weather.oy = 0 @weather.update @weather.update 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.bitmap.dispose if @snap_sprite.bitmap @snap_sprite.bitmap = Graphics.snap_to_bitmap @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 update_ground @bitmap.dispose if @bitmap @bitmap = Graphics.snap_to_bitmap next_y = @vehicle.adjust_y(0) last_oy = @vehicle.adjust_oy(0) @ground_sprites.each_with_index do |sprite, i| sprite.bitmap = @bitmap next_oy = @vehicle.adjust_oy((i + 1) * CUT) 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 next_y = @vehicle.adjust_y((i + 1) * CUT) sprite.zoom_x = @vehicle.adjust_zoom(next_y - 160) sprite.zoom_y = (next_y - sprite.y).to_f / height end end #-------------------------------------------------------------------------- # ● 乗り物の更新 #-------------------------------------------------------------------------- def update_vehicle @sprite_vehicle.update end #-------------------------------------------------------------------------- # ● 飛行船の影スプライトの更新 #-------------------------------------------------------------------------- def update_shadow if @shadow_sprite @shadow_sprite.x = Graphics.width / 2 @shadow_sprite.y = Graphics.height - 48 + @vehicle.altitude / 3 @shadow_sprite.z = @vehicle.screen_z - 1 @shadow_sprite.opacity = 255 * (90 - @vehicle.altitude / 2) / 90 @shadow_sprite.zoom_x = (200 - @vehicle.altitude) / 90.0 @shadow_sprite.zoom_y = @shadow_sprite.zoom_x end end end #////////////////////////////////////////////////////////////////////////////// # # ウィンドウ # #////////////////////////////////////////////////////////////////////////////// #============================================================================== # ■ Window_Message #============================================================================== class Window_Message #-------------------------------------------------------------------------- # ● ビューポートの設定 #-------------------------------------------------------------------------- def viewport=(viewport) super @back_sprite.viewport = viewport @gold_window.viewport = viewport @number_input_window.viewport = viewport end end #////////////////////////////////////////////////////////////////////////////// # # シーン # #////////////////////////////////////////////////////////////////////////////// #============================================================================== # ■ Scene_Map #============================================================================== class Scene_Map < Scene_Base #-------------------------------------------------------------------------- # ◯ 画面切り替えの実行 #-------------------------------------------------------------------------- alias _wooden_veh3d_update_scene_change update_scene_change def update_scene_change return if $game_player.moving? # プレイヤーの移動中? case $game_temp.next_scene when "vehicle" call_vehicle else _wooden_veh3d_update_scene_change end end #-------------------------------------------------------------------------- # ● 乗り物画面への切り替え #-------------------------------------------------------------------------- def call_vehicle $game_temp.next_scene = nil fadeout(30) $scene = Scene_Vehicle.new end end #============================================================================== # ■ Scene_Vehicle #------------------------------------------------------------------------------ #  乗り物画面の処理を行うクラスです。 #============================================================================== class Scene_Vehicle < Scene_Map #-------------------------------------------------------------------------- # ● 開始処理 #-------------------------------------------------------------------------- def start Graphics.frame_rate /= 2 Graphics.brightness = 255 $game_player.on_vehicle_start $game_map.refresh @viewport = Viewport.new(0, 0, Graphics.width, Graphics.height) @viewport.z = 200 @spriteset = Spriteset_Vehicle.new(@viewport) @message_window = Window_Message.new @message_window.viewport = @viewport end #-------------------------------------------------------------------------- # ● 終了処理 #-------------------------------------------------------------------------- def terminate $game_player.on_vehicle_end if $scene.is_a?(Scene_Map) super @viewport.dispose Graphics.frame_rate *= 2 end #-------------------------------------------------------------------------- # ● フレーム更新 #-------------------------------------------------------------------------- def update super return if $scene != self Input.update Graphics.frame_count += 1 $game_map.interpreter.update # インタプリタを更新 $game_map.update # マップを更新 $game_system.update # タイマーを更新 @message_window.update # メッセージウィンドウを更新 unless $game_message.visible # メッセージ表示中以外 update_transfer_player update_encounter update_call_menu update_call_debug update_scene_change end end #-------------------------------------------------------------------------- # ● 画面のフェードイン #-------------------------------------------------------------------------- def fadein(duration) Graphics.transition(0) for i in 0..duration-1 @viewport.color.set(0, 0, 0, 255 - 255 * (i + 1) / duration) update_basic end end #-------------------------------------------------------------------------- # ● 画面のフェードアウト #-------------------------------------------------------------------------- def fadeout(duration) Graphics.transition(0) for i in 0..duration-1 @viewport.color.set(0, 0, 0, 255 * (i + 1) / duration) update_basic end end #-------------------------------------------------------------------------- # ● 場所移動の処理 #-------------------------------------------------------------------------- def update_transfer_player return unless $game_player.transfer? fade = (Graphics.brightness > 0) fadeout(15) if fade @spriteset.dispose # スプライトセットを解放 $game_player.perform_transfer # 場所移動の実行 $game_map.autoplay # BGM と BGS の自動切り替え $game_map.update Graphics.wait(7) @spriteset = Spriteset_Vehicle.new(@viewport) fadein(15) if fade Input.update end #-------------------------------------------------------------------------- # ● キャンセルボタンによるメニュー呼び出し判定 #-------------------------------------------------------------------------- def update_call_menu end #-------------------------------------------------------------------------- # ● 画面切り替えの実行 #-------------------------------------------------------------------------- def update_scene_change return if $game_player.moving? # プレイヤーの移動中? case $game_temp.next_scene when "map" call_map else super end end #-------------------------------------------------------------------------- # ● マップ画面への切り替え #-------------------------------------------------------------------------- def call_map fadeout(15) Graphics.brightness = 0 $scene = Scene_Map.new end end #============================================================================== # ■ Scene_Menu #============================================================================== class Scene_Menu #-------------------------------------------------------------------------- # ◯ 終了処理 #-------------------------------------------------------------------------- alias _wooden_veh3d_terminate terminate def terminate if $scene.is_a?(Scene_Map) and $game_player.in_vehicle $scene = Scene_Vehicle.new end _wooden_veh3d_terminate end end #============================================================================== # ■ Scene_Item #============================================================================== class Scene_Item #-------------------------------------------------------------------------- # ◯ 終了処理 #-------------------------------------------------------------------------- alias _wooden_veh3d_terminate terminate def terminate if $scene.is_a?(Scene_Map) and $game_player.in_vehicle $scene = Scene_Vehicle.new end _wooden_veh3d_terminate end end #============================================================================== # ■ Scene_Skill #============================================================================== class Scene_Skill #-------------------------------------------------------------------------- # ◯ 終了処理 #-------------------------------------------------------------------------- alias _wooden_veh3d_terminate terminate def terminate if $scene.is_a?(Scene_Map) and $game_player.in_vehicle $scene = Scene_Vehicle.new end _wooden_veh3d_terminate end end #============================================================================== # ■ Scene_File #============================================================================== class Scene_File #-------------------------------------------------------------------------- # ◯ 終了処理 #-------------------------------------------------------------------------- alias _wooden_veh3d_terminate terminate def terminate if $scene.is_a?(Scene_Map) and $game_player.in_vehicle $scene = Scene_Vehicle.new end _wooden_veh3d_terminate end end #============================================================================== # ■ Scene_Battle #============================================================================== class Scene_Battle #-------------------------------------------------------------------------- # ◯ 終了処理 #-------------------------------------------------------------------------- alias _wooden_veh3d_terminate terminate def terminate if $scene.is_a?(Scene_Map) and $game_player.in_vehicle $scene = Scene_Vehicle.new end _wooden_veh3d_terminate end end