#============================================================================== # ■ Game_System #------------------------------------------------------------------------------ # システム周りのデータを扱うクラスです。乗り物や BGM などの管理も行います。 # このクラスのインスタンスは $game_system で参照されます。 #============================================================================== class Game_System #-------------------------------------------------------------------------- # ● 公開インスタンス変数 #-------------------------------------------------------------------------- attr_accessor :layer # レイヤー #-------------------------------------------------------------------------- # ● オブジェクト初期化 #-------------------------------------------------------------------------- alias game_system_initialize initialize def initialize game_system_initialize @layer = -1 end end #============================================================================== # ■ Game_Temp #------------------------------------------------------------------------------ # セーブデータに含まれない、一時的なデータを扱うクラスです。このクラスのイン # スタンスは $game_temp で参照されます。 #============================================================================== class Game_Temp #-------------------------------------------------------------------------- # ● 公開インスタンス変数 #-------------------------------------------------------------------------- attr_accessor :map_name #再読み込み回避 attr_accessor :link_array #再読み込み回避 attr_accessor :check #再読み込み回避 #-------------------------------------------------------------------------- # ● オブジェクト初期化 #-------------------------------------------------------------------------- alias game_temp_initialize initialize def initialize game_temp_initialize @map_name = [] #再読み込み回避 @link_array = [] #再読み込み回避 @check = false #再読み込み回避 end end #============================================================================== # ■ Game_Map #------------------------------------------------------------------------------ # マップを扱うクラスです。スクロールや通行可能判定などの機能を持っています。 # このクラスのインスタンスは $game_map で参照されます。 #============================================================================== class Game_Map #-------------------------------------------------------------------------- # ● 定数 #-------------------------------------------------------------------------- MAX_EVENT = 1000 # 1レイヤ当たりのイベント数 MAX_LAYER = 5 # レイヤの最大数 LAYER_UP = 1022 # レイヤを上げるチップID LAYER_DW = 1023 # レイヤを下げるチップID #-------------------------------------------------------------------------- # ● 公開インスタンス変数 #-------------------------------------------------------------------------- attr_accessor :name attr_accessor :para_layer attr_accessor :spe_layer attr_reader :spe_picture_name attr_reader :spe_picture_layer #-------------------------------------------------------------------------- # ● セットアップ # map_id : マップ ID # enable : 所属レイヤーの変更 #-------------------------------------------------------------------------- def setup(map_id,enable=false) ######################################################################### #レイヤー range = 0..MAX_LAYER-1 if $game_temp.check == false id_array = [] $data_mapinfos.each do | i,data | $game_temp.map_name[i] = data.name id_array.push(i) end id_array.each do | id | buf = [] name = $game_temp.map_name[id].gsub(/\<(\w+)\>/,"") name = name.gsub(/\[(\w+)\]/,"") id_array.each do | id2 | temp_name = $game_temp.map_name[id2] if temp_name.match(name) && temp_name.match(/\<lay(\d+)\>/) buf[$1.to_i] = id2 end end buf[0] = id if buf[0] == nil $game_temp.link_array[id] = buf end $game_temp.check = true end @map_id = map_id @name = $data_mapinfos[@map_id].name @map_lay = [] #各レイヤーのマップデータ @layer_no = 0 $game_player.active_layer=0 @pl_layer = 0 @name.gsub(/\<lay(\d+)\>/i) { @pl_layer = enable || $game_system.layer == -1 ? $1.to_i : $game_system.layer } $game_player.active_layer = @pl_layer #プレイヤーのレイヤーを決定 $game_player.link_layer_followers #フォロワーのレイヤーをリンク @layer_num = $game_temp.link_array[@map_id].size @map_id = $game_temp.link_array[@map_id][0] #リンクするマップをレイヤーとして読み込む @spe_picture_name = "" @para_layer = 0 $game_temp.link_array[@map_id].each do | id | @map_lay.push(load_data(sprintf("Data/Map%03d.rvdata2",id))) link_name = $game_temp.map_name[id] link_id = $game_temp.link_array[@map_id].index(id) link_name.gsub(/<para>/) { @para_layer = link_id } link_name.gsub(/\[(\w+)\]/){ set_spe_picture(link_id,$1) } end set_layer_no(0) @map_lay.each { |map| map.display_name = @map_lay[0].display_name } @display_x = [0,0,0,0,0] @display_y = [0,0,0,0,0] @speed_x = [0,0,0,0,0] @speed_y = [0,0,0,0,0] ######################################################################### @tileset_id = @map.tileset_id # @display_x = 0 # @display_y = 0 referesh_vehicles setup_events setup_scroll setup_parallax setup_battleback @need_refresh = false end #-------------------------------------------------------------------------- # ● フレーム更新 # main : インタプリタ更新フラグ #-------------------------------------------------------------------------- def update(main = false) refresh if @need_refresh update_interpreter if main update_scroll update_move_layer update_events update_vehicles update_parallax @screen.update end #-------------------------------------------------------------------------- # ● イベントのセットアップ #-------------------------------------------------------------------------- def setup_events @events = {} @map_lay.each_with_index do | map,index | map.events.each do |i, event| event.id += MAX_EVENT*index @events[i+MAX_EVENT*index] = Game_Event.new(@map_id, event) # @events[i+MAX_EVENT*index].active_layer = index end end @common_events = parallel_common_events.collect do |common_event| Game_CommonEvent.new(common_event.id) end refresh_tile_events end #-------------------------------------------------------------------------- # ● 乗っているタイルIDを取得する #-------------------------------------------------------------------------- def get_chip_id(x=$game_player.x,y=$game_player.y,layer=0) [2, 1, 0].each do |i| tile_id = @map_lay[layer].data[x, y, i] return tile_id if tile_id != 0 # タイル ID 取得できたら終了 end return nil end #-------------------------------------------------------------------------- # ● 取得するレイヤーNoの設定 #-------------------------------------------------------------------------- def set_layer_no(no) @layer_no = no @layer_no %= @layer_num @layer_no = 0 if @layer_no < 0 @map = @map_lay[@layer_no] end #-------------------------------------------------------------------------- # ● レイヤー数の取得 #-------------------------------------------------------------------------- def get_layer_num return @layer_num end #-------------------------------------------------------------------------- # ● リージョン ID の取得 #-------------------------------------------------------------------------- def region_id(x, y) valid?(x, y) ? @map_lay[$game_player.active_layer].data[x, y, 3] >> 8 : 0 end #-------------------------------------------------------------------------- # ● エンカウントリストの取得 #-------------------------------------------------------------------------- def encounter_list @map_lay[$game_player.active_layer].encounter_list end #-------------------------------------------------------------------------- # ● エンカウント歩数の取得 #-------------------------------------------------------------------------- def encounter_step @map_lay[$game_player.active_layer].encounter_step end #-------------------------------------------------------------------------- # ● マップデータの取得 #-------------------------------------------------------------------------- def data return @map_lay[@layer_no].data end #-------------------------------------------------------------------------- # ● 通行可能判定 # x : X 座標 # y : Y 座標 # flag : 調べる通行禁止ビット (通常 0x01、乗り物の場合のみ変更) #-------------------------------------------------------------------------- def passable?(x, y, d, active_layer=0) check_passage(x, y, (1 << (d / 2 - 1)) & 0x0f, active_layer) end #-------------------------------------------------------------------------- # ● 小型船の通行可能判定 #-------------------------------------------------------------------------- def boat_passable?(x, y, active_layer=0) check_passage(x, y, 0x0200, active_layer) end #-------------------------------------------------------------------------- # ● 大型船の通行可能判定 #-------------------------------------------------------------------------- def ship_passable?(x, y, active_layer=0) check_passage(x, y, 0x0400, active_layer) end #-------------------------------------------------------------------------- # ● 通行チェック # bit : 調べる通行禁止ビット #-------------------------------------------------------------------------- def check_passage(x, y, bit, active_layer) #上レイヤーの接続チップは"上"のみチェック up = false set_layer_no(active_layer+1) up = true if LAYER_UP == tile_id(x,y,2) #下レイヤーの接続チップは"下"のみチェック dw = false unless up set_layer_no(active_layer-1) dw = true if LAYER_DW == tile_id(x,y,2) end set_layer_no(active_layer) if up == false && dw == false if bit == 0x0200 || bit == 0x0400 if LAYER_DW == tile_id(x,y,2) || LAYER_UP == tile_id(x,y,2) return true end end all_tiles(x, y).each do |tile_id| flag = tileset.flags[tile_id] next if flag & 0x10 != 0 # [☆] : 通行に影響しない if flag & bit == 0 # [○] : 通行可 set_layer_no(active_layer) return true end if flag & bit == bit # [×] : 通行不可 set_layer_no(active_layer) return false end end set_layer_no(active_layer) return false # 通行不可 end #-------------------------------------------------------------------------- # ● 横方向にループするか? #-------------------------------------------------------------------------- def loop_horizontal? return (@map_lay[0].scroll_type == 2 or @map_lay[0].scroll_type == 3) end #-------------------------------------------------------------------------- # ● 縦方向にループするか? #-------------------------------------------------------------------------- def loop_vertical? return (@map_lay[0].scroll_type == 1 or @map_lay[0].scroll_type == 3) end #-------------------------------------------------------------------------- # ● ダッシュ禁止か否かの取得 #-------------------------------------------------------------------------- def disable_dash? return @map_lay[0].disable_dashing end #-------------------------------------------------------------------------- # ● 遠景のセットアップ #-------------------------------------------------------------------------- alias setup_parallax_game_map setup_parallax def setup_parallax old_map = @map @map = @map_lay[@para_layer] setup_parallax_game_map @map = old_map end #-------------------------------------------------------------------------- # ● BGM / BGS 自動切り替え #-------------------------------------------------------------------------- alias autoplay_game_map autoplay def autoplay old_map = @map @map = @map_lay[0] autoplay_game_map @map = old_map end #-------------------------------------------------------------------------- # ● 茂み判定 # x : X 座標 # y : Y 座標 #-------------------------------------------------------------------------- def bush?(x, y, layer=0) @map = @map_lay[layer] valid?(x, y) && layered_tiles_flag?(x, y, 0x40) end #-------------------------------------------------------------------------- # ● カウンター判定 # x : X 座標 # y : Y 座標 #-------------------------------------------------------------------------- def counter?(x, y, layer=0) @map = @map_lay[layer] valid?(x, y) && layered_tiles_flag?(x, y, 0x80) end #-------------------------------------------------------------------------- # ● レイヤースクロール #-------------------------------------------------------------------------- def set_move_layer(lay,speed_x,speed_y) @speed_x[lay] = speed_x @speed_y[lay] = speed_y end #-------------------------------------------------------------------------- # ● レイヤースクロール #-------------------------------------------------------------------------- def update_move_layer return if scrolling? @speed_x.each_with_index do | x,i | if x > 0 scroll_left(2 ** x.abs / 256.0,i) elsif x < 0 scroll_right(2 ** x.abs / 256.0,i) end end @speed_y.each_with_index do | y,i | if y > 0 scroll_up(2 ** y.abs / 256.0,i) elsif y < 0 scroll_down(2 ** y.abs / 256.0,i) end end end #-------------------------------------------------------------------------- # ● 表示位置の設定 # x : 新しい表示 X 座標 (*256) # y : 新しい表示 Y 座標 (*256) #-------------------------------------------------------------------------- def set_display_pos(x, y) x = [0, [x, width - screen_tile_x].min].max unless loop_horizontal? y = [0, [y, height - screen_tile_y].min].max unless loop_vertical? range = 0..4 range.each do | i | @display_x[i] = (x + width) % width @display_y[i] = (y + height) % height end @parallax_x = x @parallax_y = y end #-------------------------------------------------------------------------- # ● 表示座標を差し引いた X 座標の計算 # x : X 座標 #-------------------------------------------------------------------------- def adjust_x(x,lay=0) if loop_horizontal? && x < @display_x[lay] - (width - screen_tile_x) / 2 x - @display_x[lay] + @map.width else x - @display_x[lay] end end #-------------------------------------------------------------------------- # ● 表示座標を差し引いた Y 座標の計算 # y : Y 座標 #-------------------------------------------------------------------------- def adjust_y(y,lay=0) if loop_vertical? && y < @display_y[lay] - (height - screen_tile_y) / 2 y - @display_y[lay] + @map.height else y - @display_y[lay] end end #-------------------------------------------------------------------------- # ● 下にスクロール # distance : スクロールする距離 #-------------------------------------------------------------------------- def scroll_down(distance,lay=-1) range = lay==-1 ? 0..4 : lay..lay range.each do | i | if loop_vertical? @display_y[i] += distance @display_y[i] %= @map.height @parallax_y += distance if @parallax_loop_y && i==@para_layer else last_y = @display_y[i] @display_y[i] = [@display_y[i] + distance, height - screen_tile_y].min @parallax_y += @display_y[i] - last_y if i==@para_layer end end end #-------------------------------------------------------------------------- # ● 左にスクロール # distance : スクロールする距離 #-------------------------------------------------------------------------- def scroll_left(distance,lay=-1) range = lay==-1 ? 0..4 : lay..lay range.each do | i | if loop_horizontal? @display_x[i] += @map.width - distance @display_x[i] %= @map.width @parallax_x -= distance if @parallax_loop_x && i==@para_layer else last_x = @display_x[i] @display_x[i] = [@display_x[i] - distance, 0].max @parallax_x += @display_x[i] - last_x if i==@para_layer end end end #-------------------------------------------------------------------------- # ● 右にスクロール # distance : スクロールする距離 #-------------------------------------------------------------------------- def scroll_right(distance,lay=-1) range = lay==-1 ? 0..4 : lay..lay range.each do | i | if loop_horizontal? @display_x[i] += distance @display_x[i] %= @map.width @parallax_x += distance if @parallax_loop_x && i==@para_layer else last_x = @display_x[i] @display_x[i] = [@display_x[i] + distance, (width - screen_tile_x)].min @parallax_x += @display_x[i] - last_x if i==@para_layer end end end #-------------------------------------------------------------------------- # ● 上にスクロール # distance : スクロールする距離 #-------------------------------------------------------------------------- def scroll_up(distance,lay=-1) range = lay==-1 ? 0..4 : lay..lay range.each do | i | if loop_vertical? @display_y[i] += @map.height - distance @display_y[i] %= @map.height @parallax_y -= distance if @parallax_loop_y if i==@para_layer else last_y = @display_y[i] @display_y[i] = [@display_y[i] - distance, 0].max @parallax_y += @display_y[i] - last_y if i==@para_layer end end end #-------------------------------------------------------------------------- # ● スクロールの更新 #-------------------------------------------------------------------------- def update_scroll return unless scrolling? lay = $game_player.active_layer last_x = @display_x[lay] last_y = @display_y[lay] do_scroll(@scroll_direction, scroll_distance) if @display_x[lay] == last_x && @display_y[lay] == last_y @scroll_rest = 0 else @scroll_rest -= scroll_distance end end #-------------------------------------------------------------------------- # ● 挟み込む特殊ピクチャスプライトを表示 #-------------------------------------------------------------------------- def set_spe_picture(layer,filename) @spe_picture_name = filename @spe_picture_layer = layer end end #============================================================================== # ■ Scene_Map #------------------------------------------------------------------------------ # マップ画面の処理を行うクラスです。 #============================================================================== class Scene_Map < Scene_Base #-------------------------------------------------------------------------- # ● 公開インスタンス変数 #-------------------------------------------------------------------------- attr_accessor :spriteset #-------------------------------------------------------------------------- # ● スプライトセットの作成 #-------------------------------------------------------------------------- def create_spriteset @spriteset = Spriteset_Map_Ctrl.new end #-------------------------------------------------------------------------- # ● 場所移動の処理 #-------------------------------------------------------------------------- def perform_transfer pre_transfer $game_player.perform_transfer dispose_spriteset create_spriteset post_transfer end end #============================================================================== # ■ Spriteset_Map_Ctrl #------------------------------------------------------------------------------ # レイヤー毎に持っているスプライトセットをまとめて管理 #============================================================================== class Spriteset_Map_Ctrl #-------------------------------------------------------------------------- # ● オブジェクト初期化 #-------------------------------------------------------------------------- def initialize @spriteset = [] range = 0..$game_map.get_layer_num-1 range.each do |i| $game_map.set_layer_no(i) upper_flg = i==$game_map.get_layer_num-1 ? true : false @spriteset.push(Spriteset_Map.new(i,upper_flg)) end end #-------------------------------------------------------------------------- # ● フレーム更新 #-------------------------------------------------------------------------- def update @spriteset.each { | sprite | sprite.update } end #-------------------------------------------------------------------------- # ● 終了処理 #-------------------------------------------------------------------------- def dispose @spriteset.each { | sprite | sprite.dispose } end #-------------------------------------------------------------------------- # ● 内部のレイヤースプライトを取得 #-------------------------------------------------------------------------- def get_layer_sprite return @spriteset end #-------------------------------------------------------------------------- # ● キャラクターのスプライトを解放 #-------------------------------------------------------------------------- def dispose_characters @spriteset.each { | sprite | sprite.dispose_characters } end end #============================================================================== # ■ Spriteset_Map #------------------------------------------------------------------------------ # マップ画面のスプライトやタイルマップなどをまとめたクラスです。このクラスは # Scene_Map クラスの内部で使用されます。 #============================================================================== class Spriteset_Map #-------------------------------------------------------------------------- # ● 公開インスタンス変数 #-------------------------------------------------------------------------- attr_accessor :viewport1 attr_accessor :viewport2 attr_accessor :viewport3 attr_accessor :character_sprites #-------------------------------------------------------------------------- # ● オブジェクト初期化 #-------------------------------------------------------------------------- def initialize(pri,top) @pri = pri @top = top create_viewports create_tilemap create_parallax if update_parallaxes? create_spe_pic if update_spe? create_characters create_shadow if update? create_weather if update? create_pictures if update? create_timer if update? update end #-------------------------------------------------------------------------- # ● 解放 #-------------------------------------------------------------------------- def dispose dispose_tilemap dispose_parallax if update_parallaxes? dispose_spe_pic if update_spe? dispose_characters dispose_shadow if update? dispose_weather if update? dispose_pictures if update? dispose_timer if update? dispose_viewports end #-------------------------------------------------------------------------- # ● フレーム更新 #-------------------------------------------------------------------------- def update $game_map.set_layer_no(@pri) update_tileset update_tilemap update_parallax if update_parallaxes? update_spe_pic if update_spe? update_characters update_shadow if update? update_weather if update? update_pictures if update? update_timer if update? update_viewports end #-------------------------------------------------------------------------- # ● タイルマップの作成 #-------------------------------------------------------------------------- alias create_tilemap_layer create_tilemap def create_tilemap create_tilemap_layer refresh_tilemap end #-------------------------------------------------------------------------- # ● タイルマップの作成 #-------------------------------------------------------------------------- def refresh_tilemap erase_tile(Game_Map::LAYER_UP) erase_tile(Game_Map::LAYER_DW) end #-------------------------------------------------------------------------- # ● いらないタイルを消す #-------------------------------------------------------------------------- def erase_tile(id) x=(id%8)*32 + 256*(id/888) y=(id-768)/8*32 - 512*(id/888) @tilemap.bitmaps[8].clear_rect(x, y, 32, 32) end #-------------------------------------------------------------------------- # ● キャラクタースプライトの作成 #-------------------------------------------------------------------------- def create_characters @character_sprites = [] $game_map.events.values.each do |event| @character_sprites.push(Sprite_Character.new(@viewport1, event, @pri)) end $game_map.vehicles.each do |vehicle| @character_sprites.push(Sprite_Character.new(@viewport1, vehicle, @pri)) end $game_player.followers.reverse_each do |follower| @character_sprites.push(Sprite_Character.new(@viewport1, follower, @pri)) end @character_sprites.push(Sprite_Character.new(@viewport1, $game_player, @pri)) @map_id = $game_map.map_id end #-------------------------------------------------------------------------- # ● アップデートするか? #-------------------------------------------------------------------------- def update? return true if @pri==0 return false end #-------------------------------------------------------------------------- # ● アップデートするか?(遠景) #-------------------------------------------------------------------------- def update_parallaxes? return @pri==$game_map.para_layer ? true : false end #-------------------------------------------------------------------------- # ● アップデートするか?(最上層) #-------------------------------------------------------------------------- def update_top? return @top end #-------------------------------------------------------------------------- # ● アップデートするか?(挟み込むピクチャ) #-------------------------------------------------------------------------- def update_spe? return @pri==$game_map.spe_picture_layer ? true : false end #-------------------------------------------------------------------------- # ● ビューポートの更新 #-------------------------------------------------------------------------- def update_viewports if update_top? @viewport1.tone = $game_map.screen.tone end @viewport1.ox = $game_map.screen.shake if update_top? @viewport2.color = $game_map.screen.flash_color @viewport3.color.set(0, 0, 0, 255 - $game_map.screen.brightness) end @viewport1.update @viewport2.update @viewport3.update end #-------------------------------------------------------------------------- # ● タイルマップの更新 #-------------------------------------------------------------------------- def update_tilemap @tilemap.map_data = $game_map.data @tilemap.ox = $game_map.display_x[@pri] * 32 @tilemap.oy = $game_map.display_y[@pri] * 32 @tilemap.update end #-------------------------------------------------------------------------- # ● 天候の更新 #-------------------------------------------------------------------------- def update_weather @weather.type = $game_map.screen.weather_type @weather.power = $game_map.screen.weather_power @weather.ox = $game_map.display_x[@pri] * 32 @weather.oy = $game_map.display_y[@pri] * 32 @weather.update end #-------------------------------------------------------------------------- # ● 挟み込む特殊ピクチャスプライトを作成 #-------------------------------------------------------------------------- def create_spe_pic @layer_sprite = Sprite.new @filename = "" @old_filename = "" end #-------------------------------------------------------------------------- # ● 挟み込む特殊ピクチャスプライトを更新 #-------------------------------------------------------------------------- def update_spe_pic @layer_sprite.update filename = $game_map.spe_picture_name if @pri == $game_map.spe_picture_layer && filename != @old_filename if filename != "" name = "Graphics/Pictures/" + $game_map.spe_picture_name @layer_sprite.bitmap = Bitmap.new(name) @layer_sprite.wave_amp = 5 @layer_sprite.wave_length = 5 @layer_sprite.wave_speed = 20 @layer_sprite.x = -20 @layer_sprite.y = 0 @layer_sprite.z = 0 @layer_sprite.opacity = 200 @layer_sprite.visible = true else @layer_sprite.visible = false end @old_filename = filename end end #-------------------------------------------------------------------------- # ● 挟み込む特殊ピクチャスプライトを解放 #-------------------------------------------------------------------------- def dispose_spe_pic @layer_sprite.dispose if @layer_sprite != nil end #-------------------------------------------------------------------------- # ● タイルセットの更新 #-------------------------------------------------------------------------- def update_tileset if @tileset != $game_map.tileset load_tileset refresh_characters refresh_tilemap end end end #============================================================================== # ■ Game_Player #------------------------------------------------------------------------------ # プレイヤーを扱うクラスです。イベントの起動判定や、マップのスクロールなどの # 機能を持っています。このクラスのインスタンスは $game_player で参照されます。 #============================================================================== class Game_Player < Game_Character #-------------------------------------------------------------------------- # ● マップ通行可能判定 # d : 方向(2,4,6,8) #-------------------------------------------------------------------------- def map_passable?(x, y, d) case @vehicle_type when :boat $game_map.boat_passable?(x, y, @active_layer) when :ship $game_map.ship_passable?(x, y, @active_layer) when :airship true else super end end #-------------------------------------------------------------------------- # ● 場所移動の実行 #-------------------------------------------------------------------------- def perform_transfer if transfer? set_direction(@new_direction) if @new_map_id != $game_map.map_id $game_map.setup(@new_map_id,true) # レイヤー間を移動するので常にセット $game_map.autoplay end moveto(@new_x, @new_y) link_layer_followers clear_transfer_info end end #-------------------------------------------------------------------------- # ● マップイベントの起動 # triggers : トリガーの配列 # normal : プライオリティ[通常キャラと同じ]かそれ以外か #-------------------------------------------------------------------------- def start_map_event(x, y, triggers, normal) $game_map.events_xy(x, y).each do |event| next unless check_enable_layer(event) if event.trigger_in?(triggers) && event.normal_priority? == normal event.start end end end #-------------------------------------------------------------------------- # ● 更新 #-------------------------------------------------------------------------- alias game_player_update update def update game_player_update $game_system.layer = $game_player.active_layer end #-------------------------------------------------------------------------- # ● 乗り物に乗る # 現在乗り物に乗っていないことが前提。 #-------------------------------------------------------------------------- def get_on_vehicle add = 0 check_layer = (@active_layer + 1) % $game_map.get_layer_num add = 1 if $game_map.get_chip_id(self.x, self.y, check_layer) == Game_Map::LAYER_DW check_layer = (@active_layer - 1) % $game_map.get_layer_num add =-1 if $game_map.get_chip_id(self.x, self.y, check_layer) == Game_Map::LAYER_UP front_x = $game_map.x_with_direction(@x, @direction) front_y = $game_map.y_with_direction(@y, @direction) @vehicle_type = :boat if $game_map.boat.pos?(front_x, front_y) && @active_layer+add == $game_map.boat.active_layer # 正面に大型船がある? @vehicle_type = :ship if $game_map.ship.pos?(front_x, front_y) && @active_layer+add == $game_map.ship.active_layer # 正面に小型船がある? @vehicle_type = :airship if $game_map.airship.pos?(@x, @y) if vehicle @vehicle_getting_on = true force_move_forward unless in_airship? @followers.gather end @vehicle_getting_on end #-------------------------------------------------------------------------- # ● 乗り物から降りる # 現在乗り物に乗っていることが前提。 #-------------------------------------------------------------------------- alias game_player_get_off_vehicle get_off_vehicle def get_off_vehicle front_x = $game_map.x_with_direction(@x, @direction) front_y = $game_map.y_with_direction(@y, @direction) id0 = $game_map.get_chip_id(front_x, front_y, @active_layer) id1 = $game_map.get_chip_id(front_x, front_y, (@active_layer+1)%$game_map.get_layer_num) return if id0 == Game_Map::LAYER_UP || id0 == Game_Map::LAYER_DW return if id1 == Game_Map::LAYER_UP || id1 == Game_Map::LAYER_DW game_player_get_off_vehicle end #-------------------------------------------------------------------------- # ● スクロール処理 #-------------------------------------------------------------------------- def update_scroll(last_real_x, last_real_y) ax1 = $game_map.adjust_x(last_real_x, @active_layer) ay1 = $game_map.adjust_y(last_real_y, @active_layer) ax2 = $game_map.adjust_x(@real_x, @active_layer) ay2 = $game_map.adjust_y(@real_y, @active_layer) $game_map.scroll_down (ay2 - ay1) if ay2 > ay1 && ay2 > center_y $game_map.scroll_left (ax1 - ax2) if ax2 < ax1 && ax2 < center_x $game_map.scroll_right(ax2 - ax1) if ax2 > ax1 && ax2 > center_x $game_map.scroll_up (ay1 - ay2) if ay2 < ay1 && ay2 < center_y end #-------------------------------------------------------------------------- # ● フォロワーのレイヤーをリンクする #-------------------------------------------------------------------------- def link_layer_followers @followers.each { |f| f.active_layer = @active_layer } end end #============================================================================== # ■ Game_Vehicle #------------------------------------------------------------------------------ # 乗り物を扱うクラスです。このクラスは Game_Map クラスの内部で使用されます。 # 現在のマップに乗り物がないときは、マップ座標 (-1,-1) に設定されます。 #============================================================================== class Game_Vehicle < Game_Character #-------------------------------------------------------------------------- # ● 接岸/着陸可能判定 # d : 方向(2,4,6,8) #-------------------------------------------------------------------------- def land_ok?(x, y, d) if @type == :airship return false unless $game_map.airship_land_ok?(x, y) return false unless $game_map.events_xy(x, y).empty? 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), @active_layer) return false if collide_with_characters?(x2, y2) end return true end end #============================================================================== # ■ Game_Event #------------------------------------------------------------------------------ # イベントを扱うクラスです。条件判定によるイベントページ切り替えや、並列処理 # イベント実行などの機能を持っており、Game_Map クラスの内部で使用されます。 #============================================================================== class Game_Event < Game_Character #-------------------------------------------------------------------------- # ● 公開インスタンス変数 #-------------------------------------------------------------------------- attr_accessor :id #-------------------------------------------------------------------------- # ● オブジェクト初期化 # event : RPG::Event #-------------------------------------------------------------------------- def initialize(map_id, event) super() @map_id = map_id @event = event @id = @event.id self.active_layer = @id / Game_Map::MAX_EVENT moveto(@event.x, @event.y) refresh end #-------------------------------------------------------------------------- # ● 接触イベントの起動判定 #-------------------------------------------------------------------------- def check_event_trigger_touch(x, y) return if $game_map.interpreter.running? if @trigger == 2 && $game_player.pos?(x, y) && check_enable_layer($game_player) start if !jumping? && normal_priority? end end #-------------------------------------------------------------------------- # ● 画面の可視領域付近にいるか判定 # dx : 画面中央から左右何マス以内を判定するか # dy : 画面中央から上下何マス以内を判定するか #-------------------------------------------------------------------------- def near_the_screen?(dx = 12, dy = 8) ax = $game_map.adjust_x(@real_x,@active_layer) - Graphics.width / 2 / 32 ay = $game_map.adjust_y(@real_y,@active_layer) - Graphics.height / 2 / 32 ax >= -dx && ax <= dx && ay >= -dy && ay <= dy end end #============================================================================== # ■ Game_CharacterBase #------------------------------------------------------------------------------ # キャラクターを扱う基本のクラスです。全てのキャラクターに共通する、座標やグ # ラフィックなどの基本的な情報を保持します。 #============================================================================== class Game_CharacterBase #-------------------------------------------------------------------------- # ● 公開インスタンス変数 #-------------------------------------------------------------------------- attr_accessor :active_layer #-------------------------------------------------------------------------- # ● オブジェクト初期化 #-------------------------------------------------------------------------- alias initialize2 initialize def initialize initialize2 @active_layer = 0 end #-------------------------------------------------------------------------- # ● フレーム更新 #-------------------------------------------------------------------------- def update update_layer_change update_animation return update_jump if jumping? return update_move if moving? return update_stop end #-------------------------------------------------------------------------- # ● 所属レイヤーの変更 #-------------------------------------------------------------------------- def update_layer_change return false if $game_map.get_layer_num == 1 return if @old_x == self.x && @old_y == self.y if @active_layer+1 < $game_map.get_layer_num id = $game_map.get_chip_id(self.x,self.y,@active_layer+1) @active_layer=@active_layer+1 if id == Game_Map::LAYER_UP end if @active_layer-1 > -1 id = $game_map.get_chip_id(self.x,self.y,@active_layer-1) @active_layer=@active_layer-1 if id == Game_Map::LAYER_DW end @old_x = self.x @old_y = self.y end #-------------------------------------------------------------------------- # ● キャラクター衝突判定 # x : X 座標 # y : Y 座標 # プレイヤーと乗り物を含め、通常キャラの衝突を検出する。 #-------------------------------------------------------------------------- def collide_with_characters?(x, y) #一歩前を見るのでこの形に add = 0 check_layer = (@active_layer + 1) % $game_map.get_layer_num add = 1 if $game_map.get_chip_id(x, y, check_layer) == Game_Map::LAYER_UP check_layer = (@active_layer - 1) % $game_map.get_layer_num add =-1 if $game_map.get_chip_id(x, y, check_layer) == Game_Map::LAYER_DW collide_with_events?(x, y, add) || collide_with_vehicles?(x, y, add) end #-------------------------------------------------------------------------- # ● イベントとの衝突判定 #-------------------------------------------------------------------------- def collide_with_events?(x, y, add=0) $game_map.events_xy_nt(x, y).any? do |event| if event.active_layer == @active_layer || event.active_layer == @active_layer+add event.normal_priority? || self.is_a?(Game_Event) end end end #-------------------------------------------------------------------------- # ● 乗り物との衝突判定 #-------------------------------------------------------------------------- def collide_with_vehicles?(x, y, add=0) collide_with_boat?(x, y, add) || collide_with_ship?(x, y, add) end #-------------------------------------------------------------------------- # ● 大型船との衝突判定 #-------------------------------------------------------------------------- def collide_with_ship?(x, y, add=0) if $game_map.ship.active_layer != @active_layer+add && $game_map.ship.active_layer != @active_layer return false end $game_map.ship.pos_nt?(x, y) end #-------------------------------------------------------------------------- # ● 小型船との衝突判定 #-------------------------------------------------------------------------- def collide_with_boat?(x, y, add=0) if $game_map.boat.active_layer != @active_layer+add && $game_map.boat.active_layer != @active_layer return false end $game_map.boat.pos_nt?(x, y) end #-------------------------------------------------------------------------- # ● 位置設定(イベント位置設定用) #-------------------------------------------------------------------------- def set_pos(new_x,new_y,dir=@direction,lay=@active_layer) moveto(new_x, new_y) set_active_layer(lay) case dir # 向き when 8 # 上 turn_up when 6 # 右 turn_right when 2 # 下 turn_down when 4 # 左 turn_left end end #-------------------------------------------------------------------------- # ● 茂み判定 #-------------------------------------------------------------------------- def bush? $game_map.bush?(@x, @y, @active_layer) end #-------------------------------------------------------------------------- # ● マップ通行可能判定 # x : X 座標 # y : Y 座標 #-------------------------------------------------------------------------- def map_passable?(x, y, d) $game_map.passable?(x, y, d, @active_layer) end #-------------------------------------------------------------------------- # ● 違うレイヤーのイベント起動判定 #-------------------------------------------------------------------------- def check_enable_layer(object) #自分が「上」に乗っている時 #自分は今のレイヤーと一つ下のレイヤーをチェックするはず id = $game_map.get_chip_id(self.x, self.y, @active_layer) if id == Game_Map::LAYER_UP layer =(@active_layer-1) % $game_map.get_layer_num return true if object.active_layer == @active_layer return true if object.active_layer == @active_layer-1 end #自分が「下」に乗っている時 #自分は今のレイヤーと一つ上のレイヤーをチェックするはず id = $game_map.get_chip_id(self.x, self.y, @active_layer) if id == Game_Map::LAYER_DW layer =(@active_layer+1) % $game_map.get_layer_num return true if object.active_layer == @active_layer return true if object.active_layer == @active_layer+1 end #どちらでもない場合 return true if object.active_layer == @active_layer return false end #-------------------------------------------------------------------------- # ● 画面 X 座標の取得 #-------------------------------------------------------------------------- def screen_x $game_map.adjust_x(@real_x,@active_layer) * 32 + 16 end #-------------------------------------------------------------------------- # ● 画面 Y 座標の取得 #-------------------------------------------------------------------------- def screen_y $game_map.adjust_y(@real_y,@active_layer) * 32 + 32 - shift_y - jump_height end #-------------------------------------------------------------------------- # ● 所属レイヤーのセット #-------------------------------------------------------------------------- def set_active_layer(no) @active_layer = no end end #============================================================================== # ■ Sprite_Character #------------------------------------------------------------------------------ # キャラクター表示用のスプライトです。Game_Character クラスのインスタンスを # 監視し、スプライトの状態を自動的に変化させます。 #============================================================================== class Sprite_Character < Sprite_Base #-------------------------------------------------------------------------- # ● オブジェクト初期化 # viewport : ビューポート # character : キャラクター (Game_Character) #-------------------------------------------------------------------------- alias sprite_character_initialize initialize def initialize(viewport, character = nil, layer = 0) @layer = layer sprite_character_initialize(viewport, character) end #-------------------------------------------------------------------------- # ● フレーム更新 #-------------------------------------------------------------------------- alias sprite_character_update update def update unless update? self.visible = false return end sprite_character_update end #-------------------------------------------------------------------------- # ● フレーム更新を行うか? #-------------------------------------------------------------------------- def update? test_x = @character.x test_y = @character.y char_layer = @character.active_layer #キャラクターのレイヤー range = 0..3 check_pos_x = [test_x,test_x,test_x-1,test_x+1] check_pos_y = [test_y-1,test_y+1,test_y,test_y] if char_layer+1 == @layer range.each do | i | id = $game_map.get_chip_id(check_pos_x[i],check_pos_y[i],@layer) return true if id == Game_Map::LAYER_UP end end if char_layer == @layer range.each do | i | id = $game_map.get_chip_id(check_pos_x[i],check_pos_y[i],@layer) return true if id != Game_Map::LAYER_UP end end return false end #-------------------------------------------------------------------------- # ● 位置の更新 #-------------------------------------------------------------------------- def update_position self.x = @character.screen_x.round self.y = @character.screen_y.round self.z = @character.screen_z end end #============================================================================== # ■ Game_Interpreter #------------------------------------------------------------------------------ # イベントコマンドを実行するインタプリタです。このクラスは Game_Map クラス、 # Game_Troop クラス、Game_Event クラスの内部で使用されます。 #============================================================================== class Game_Interpreter #-------------------------------------------------------------------------- # ● イベントのセットアップ # list : 実行内容 # event_id : イベント ID #-------------------------------------------------------------------------- alias Game_Interpreter_setup setup def setup(list, event_id = 0) Game_Interpreter_setup(list, event_id) #どのレイヤーのイベントが起動したか @setup_layer = event_id / Game_Map::MAX_EVENT end #-------------------------------------------------------------------------- # ● レイヤーの変更 #-------------------------------------------------------------------------- def set_active_layer(lay) $game_map.events[@event_id].active_layer=lay if @event_id > 0 end #-------------------------------------------------------------------------- # ● キャラクターの取得 # param : -1 ならプレイヤー、0 ならこのイベント、それ以外はイベント ID #-------------------------------------------------------------------------- def get_character(param) if $game_party.in_battle nil elsif param < 0 $game_player else events = same_map? ? $game_map.events : {} add = @setup_layer * Game_Map::MAX_EVENT events[param > 0 ? param+add : @event_id] end end end
1.8 MB, 下载次数: 40
范例
欢迎光临 Project1 (https://rpg.blue/) | Powered by Discuz! X3.1 |