#============================================================================== # ■ XP-RGSS-50 ワールドマップ [ウィンドウ] by Claimh #============================================================================== #============================================================================== # ■ Window_Region #============================================================================== class Window_Region < Window_Selectable attr_reader :region_list # 地域・地点リスト attr_accessor :back_sprite # 背景画 attr_accessor :town_window # 地点ウィンドウ #-------------------------------------------------------------------------- # ● オブジェクト初期化 # actor : アクター #-------------------------------------------------------------------------- def initialize(region_list, region_id) @temp_top_row = 0 @region_list = region_list super(0, 0, 200, 64) self.windowskin = RPG::Cache.windowskin(WorldMap::W_WINSKIN) self.back_opacity = WorldMap::W_SKIN_OPACITY @column_max = 1 @back_sprite = nil @town_window = nil for i in 0...region_list.size if region_id == region_list[i].region_id @index = i break end end @page_index = -1 refresh reset_height end #-------------------------------------------------------------------------- # ● 有効リージョン? #-------------------------------------------------------------------------- def r_enable? return false if @region_list[@index].nil? return @region_list[@index].enable end #-------------------------------------------------------------------------- # ● リフレッシュ #-------------------------------------------------------------------------- def refresh if self.contents != nil self.contents.dispose self.contents = nil end @item_max = @region_list.size # 項目数が 0 でなければビットマップを作成し、全項目を描画 if @item_max > 0 self.contents = Bitmap.new(width - 32, @item_max * 32) for i in 0...@item_max draw_item(i) end end end #-------------------------------------------------------------------------- # ● 項目の描画 # index : 項目番号 #-------------------------------------------------------------------------- def draw_item(index) x = 4 y = index / @column_max * 32 rect = Rect.new(x, y, self.width / @column_max - 32, 32) self.contents.fill_rect(rect, Color.new(0, 0, 0, 0)) self.contents.font.color = normal_color self.contents.font.color.alpha = @region_list[index].enable ? 255 : 128 self.contents.draw_text(x, y, 204, 32, @region_list[index].region_name, 0) end #-------------------------------------------------------------------------- # ● ヘルプテキスト更新 #-------------------------------------------------------------------------- def update_help if @page_index != @index @page_index = @index return if @region_list[@index].nil? unless @help_window.nil? name = @region_list[@index].region_name # ヘルプウィンドウ更新 @help_window.set_info(@region_list[@index].region_info) end unless @back_sprite.nil? # 背景画切り替え(中央表示) @back_sprite.region_id = @region_list[@index].region_id @back_sprite.show_center(@region_list[@index].region_map) end unless @town_window.nil? town_list = $game_system.worldmap.make_town_list(@region_list[@index]) # ヘルプウィンドウ更新 @town_window.set_town(town_list) end end end def p_updete_help @page_index = -10 update_help end #-------------------------------------------------------------------------- # ● 高さリセット #-------------------------------------------------------------------------- def reset_height self.height = ((@region_list.size > WorldMap::LIST_MAX ? WorldMap::LIST_MAX : @region_list.size) + 1) * 32 self.top_row = @temp_top_row update_cursor_rect end #-------------------------------------------------------------------------- # ● 高さ縮小 #-------------------------------------------------------------------------- def resize_height self.height = 64 @temp_top_row = self.top_row update_cursor_rect end #-------------------------------------------------------------------------- # ● LRボタン用更新 #-------------------------------------------------------------------------- def update_LR # カーソルの移動が可能な状態の場合 if @item_max > 1 and @index >= 0 # Rボタンが押された場合 if Input.repeat?(Input::R) # 列数が 1 かつ 方向ボタンの下の押下状態がリピートでない場合か、 # またはカーソル位置が(項目数 - 列数)より前の場合 if (@column_max == 1 and Input.trigger?(Input::R)) or @index < @item_max - @column_max # カーソルを下に移動 $game_system.se_play($data_system.cursor_se) @index = (@index + @column_max) % @item_max end end # Lボタンが押された場合 if Input.repeat?(Input::L) # 列数が 1 かつ 方向ボタンの上の押下状態がリピートでない場合か、 # またはカーソル位置が列数より後ろの場合 if (@column_max == 1 and Input.trigger?(Input::L)) or @index >= @column_max # カーソルを上に移動 $game_system.se_play($data_system.cursor_se) @index = (@index - @column_max + @item_max) % @item_max end end update_help end end end #============================================================================== # ■ Window_Town #============================================================================== class Window_Town < Window_Selectable attr_reader :town_list # 地域・地点リスト attr_accessor :help_arrow # 関連アロー attr_accessor :move_sprite # 背景画移動 attr_accessor :town_window # 地点ウィンドウ #-------------------------------------------------------------------------- # ● オブジェクト初期化 # actor : アクター #-------------------------------------------------------------------------- def initialize(town_list, town_id) @temp_top_row = 0 @town_list = town_list super(440, 0, 200, 64) self.windowskin = RPG::Cache.windowskin(WorldMap::W_WINSKIN) self.back_opacity = WorldMap::W_SKIN_OPACITY @column_max = 1 @help_arrow = nil @move_sprite = nil @town_window = nil for i in 0...town_list.size if town_id == town_list[i].town_id @index = i break end end @index_refain = -1 @index_townname = -1 @counting = 0 @degree = false refresh reset_height end #-------------------------------------------------------------------------- # ● 高さリセット #-------------------------------------------------------------------------- def reset_height self.height = ((@town_list.size > WorldMap::LIST_MAX ? WorldMap::LIST_MAX : @town_list.size) + 1) * 32 self.top_row = @temp_top_row update_cursor_rect end #-------------------------------------------------------------------------- # ● 高さ縮小 #-------------------------------------------------------------------------- def resize_height self.height = 64 @temp_top_row = self.top_row update_cursor_rect end #-------------------------------------------------------------------------- # ● 有効タウン? #-------------------------------------------------------------------------- def t_enable? return false if @town_list[@index].nil? return @town_list[@index].enable end #-------------------------------------------------------------------------- # ● リフレッシュ #-------------------------------------------------------------------------- def refresh if self.contents != nil self.contents.dispose self.contents = nil end @item_max = @town_list.size # 項目数が 0 でなければビットマップを作成し、全項目を描画 if @item_max > 0 self.contents = Bitmap.new(width - 32, @item_max * 32) for i in 0...@item_max draw_item(i) end end end #-------------------------------------------------------------------------- # ● 項目の描画 # index : 項目番号 #-------------------------------------------------------------------------- def draw_item(index) x = 4 y = index / @column_max * 32 rect = Rect.new(x, y, self.width / @column_max - 32, 32) self.contents.fill_rect(rect, Color.new(0, 0, 0, 0)) self.contents.font.color = normal_color self.contents.font.color.alpha = @town_list[index].enable ? 255 : 128 self.contents.draw_text(x, y, 204, 32, @town_list[index].town_name, 0) end #-------------------------------------------------------------------------- # ● タウン情報を返す #-------------------------------------------------------------------------- def return_town return @town_list[@index] end #-------------------------------------------------------------------------- # ● キャンセル動作 #-------------------------------------------------------------------------- def cancel @degree = true @index_townname = -1 @move_sprite.move_center(0) end def cancel_current @degree = true @index_townname = -1 @move_sprite.current_center = true end #-------------------------------------------------------------------------- # ● 4方向カーソル選択 #-------------------------------------------------------------------------- def update_dir4 if Input::trigger?(Input::UP) $game_system.se_play($data_system.cursor_se) index_up elsif Input::trigger?(Input::DOWN) $game_system.se_play($data_system.cursor_se) index_down elsif Input::trigger?(Input::LEFT) $game_system.se_play($data_system.cursor_se) index_left elsif Input::trigger?(Input::RIGHT) $game_system.se_play($data_system.cursor_se) index_right end end # town_id -> list.index def list_search(list, town_id) for i in 0...list.size if list[i].town_id == town_id return i end end end # sort up-down list def list_ud return @town_list.sort {|a,b| a.map_pos.y - b.map_pos.y } end # change index [UP] def index_up list = WorldMap::CUR_MAP_POS ? list_ud : @town_list list_i = list_search(list, @town_list[@index].town_id) list_i = (list_i - 1 + list.size) % list.size @index = list_search(@town_list, list[list_i].town_id) end # change index [DOWN] def index_down list = WorldMap::CUR_MAP_POS ? list_ud : @town_list list_i = list_search(list, @town_list[@index].town_id) list_i = (list_i + 1) % list.size @index = list_search(@town_list, list[list_i].town_id) end # sort left-right list def list_lr return @town_list.sort {|a,b| a.map_pos.x - b.map_pos.x } end # change index [LEFT] def index_left list = WorldMap::CUR_MAP_POS ? list_lr : @town_list list_i = list_search(list, @town_list[@index].town_id) list_i = (list_i - 1 + list.size) % list.size @index = list_search(@town_list, list[list_i].town_id) end # change index [RIGHT] def index_right list = WorldMap::CUR_MAP_POS ? list_lr : @town_list list_i = list_search(list, @town_list[@index].town_id) list_i = (list_i + 1) % list.size @index = list_search(@town_list, list[list_i].town_id) end #-------------------------------------------------------------------------- # ● 地点情報更新 #-------------------------------------------------------------------------- def set_town(info) if @town_list != info @town_list = info if WorldMap::USE_LIST self.visible = (info.size > 0) refresh reset_height else refresh @index = 0 end end end #-------------------------------------------------------------------------- # ● ヘルプテキスト更新 #-------------------------------------------------------------------------- def update_help # テキストウィンドウ更新 unless @help_window.nil? # ヘルプウィンドウ更新 @help_window.set_info(@town_list[@index].town_info) end # マップスプライト更新 unless @move_sprite.nil? if WorldMap::W_CENTARING # Window_Selectableの制限によりindex切り替えを検知して実行する if @index_refain != @index if WorldMap::BACK_ZOOM # 中心へ移動 @move_sprite.move_center(WorldMap::W_SELECT_BACK) end @index_refain = @index @counting = 0 @degree = true else # すぐに切り替えはしない。 if @counting < WorldMap::W_SELECT_BACK_SKIP @counting += 1 return end if @degree @degree = false # 背景画、移動 # move(duration, x, y, zoom_x, zoom_y, opacity, blend_type) @move_sprite.move(WorldMap::W_SELECT_T, @town_list[@index].map_pos.x, @town_list[@index].map_pos.y, WorldMap::W_SELECT_Z, WorldMap::W_SELECT_Z, 255, 0) end end else @index_refain = @index @degree = false end end # 移動地点アロー更新 unless @help_arrow.nil? if @move_sprite.move_finish? and @index_refain == @index and !@degree # 関連アロー表示 @help_arrow.visible = true # 関連アロー位置更新 if WorldMap::W_CENTARING @help_arrow.update_point(WorldMap::Position.new(320,240), @town_list[@index].icon.nil?) else @help_arrow.update_point(@town_list[@index].map_pos, @town_list[@index].icon.nil?) end else # 関連アロー消す @help_arrow.visible = false end end # 移動地点名更新 unless @town_window.nil? # 切り替え時にウィンドウ消去 if @index != @index_townname @index_townname = @index @town_window.visible = false else if @move_sprite.move_finish? and !@town_window.visible # 地点名表示 @town_window.set_info(@town_list[@index]) @town_window.visible = true end end end end end #============================================================================== # ■ Window_TownName #============================================================================== class Window_TownName < Window_Base #-------------------------------------------------------------------------- # ● オブジェクト初期化 #-------------------------------------------------------------------------- def initialize super(320, 180, 160, 64) self.windowskin = RPG::Cache.windowskin(WorldMap::W_WINSKIN) self.visible = false self.opacity = 0 @info_text = nil end #-------------------------------------------------------------------------- # ● 更新 #-------------------------------------------------------------------------- def refresh self.contents.dispose unless self.contents.nil? self.contents = Bitmap.new(self.width - 32, self.height - 32) return if @info_text.nil? # 説明表示 self.contents.fill_rect(self.contents.rect, Color.new(128,128,128,128)) # self.contents.font.color = Color.new(255, 64, 0) # self.contents.font.italic = true self.contents.draw_text(0, 0, self.width-32, 32, @info_text, 1) end #-------------------------------------------------------------------------- # ● ヘルプテキスト更新 #-------------------------------------------------------------------------- def set_info(info) if @info_text != info @info_text = info.town_name self.visible = true self.width = Bitmap.new(10, 10).text_size(@info_text).width + 64 if WorldMap::W_CENTARING self.x = 320 - (self.width/2) else self.x = info.map_pos.x - (self.width/2) self.y = info.map_pos.y - (self.height) end # ヘルプウィンドウ更新 refresh end end end #============================================================================== # ■ Window_WorldInfo #============================================================================== class Window_WorldInfo < Window_Base #-------------------------------------------------------------------------- # ● オブジェクト初期化 #-------------------------------------------------------------------------- def initialize h = WorldMap::INFO_MAX * 32 + 32 super(0, 480-h, 640, h) self.windowskin = RPG::Cache.windowskin(WorldMap::W_WINSKIN) self.contents = Bitmap.new(width - 32, height - 32) self.back_opacity = WorldMap::W_SKIN_OPACITY @info_text = nil refresh end #-------------------------------------------------------------------------- # ● アロー更新 #-------------------------------------------------------------------------- def refresh self.contents.clear return if @info_text.nil? self.visible = @info_text == "" ? false : true WorldMap.draw_info_text(self.contents, 0, 0, self.width, 32, @info_text) end #-------------------------------------------------------------------------- # ● ヘルプテキスト更新 #-------------------------------------------------------------------------- def set_info(info) if @info_text != info @info_text = info # ヘルプウィンドウ更新 refresh end end end #============================================================================== # ■ Arrow_TownPoint #============================================================================== class Arrow_TownPoint < Sprite M_WIN = 0 M_CHF = 1 M_CHB = 2 attr_reader :index # カーソル位置 #-------------------------------------------------------------------------- # ● オブジェクト初期化 # viewport : ビューポート #-------------------------------------------------------------------------- def initialize(viewport) super(viewport) @time = WorldMap::W_ARROW_TIME @mode = WorldMap::W_ARROW_TYPE ? M_CHF : M_WIN case @mode when M_WIN self.bitmap = RPG::Cache.windowskin(WorldMap::W_ARROWSKIN) @rect = Rect.new(0, 0, 32, 32) self.src_rect.set(128, 96, @rect.width, @rect.width) @max = 2 * @time when M_CHF self.bitmap = RPG::Cache.character($game_party.actors[0].character_name, $game_party.actors[0].character_hue) @rect = Rect.new(0, 0, self.bitmap.width / 4, self.bitmap.height / 4) self.src_rect.set(0, 0, @rect.width, @rect.height) @max = 4 * @time end self.ox = 16 self.oy = 0 self.z = 100 self.visible = false @blink_count = 0 @index = 0 update end #-------------------------------------------------------------------------- # ● 後ろ向きにする #-------------------------------------------------------------------------- def change_char_back @mode = M_CHB self.src_rect.set(0, @rect.height * 3, @rect.width, @rect.height) @blink_count = 0 end #-------------------------------------------------------------------------- # ● 位置更新 #-------------------------------------------------------------------------- def update_point(point, not_use_icon=true) self.x = point.x + 2 # Windowskin素材による中心補正 self.y = point.y + (not_use_icon ? 0 : (@rect.width / 2)) end #-------------------------------------------------------------------------- # ● カーソル位置の設定 # index : 新しいカーソル位置 #-------------------------------------------------------------------------- def index=(index) @index = index update end #-------------------------------------------------------------------------- # ● フレーム更新 #-------------------------------------------------------------------------- def update # 点滅カウントを更新 @blink_count = (@blink_count + 1) % @max # 転送元の矩形を設定 case @mode when M_WIN case @blink_count when (@time * 0); self.src_rect.set(128, 96, 32, 32) when (@time * 1); self.src_rect.set(160, 96, 32, 32) end when M_CHF w = @rect.width; h = @rect.height case @blink_count when (@time * 0); self.src_rect.set(w * 0, h * 0, w, h) when (@time * 1); self.src_rect.set(w * 1, h * 0, w, h) when (@time * 2); self.src_rect.set(w * 2, h * 0, w, h) when (@time * 3); self.src_rect.set(w * 3, h * 0, w, h) end when M_CHB w = @rect.width; h = @rect.height case @blink_count when (@time * 0); self.src_rect.set(w * 0, h * 3, w, h) when (@time * 1); self.src_rect.set(w * 1, h * 3, w, h) when (@time * 2); self.src_rect.set(w * 2, h * 3, w, h) when (@time * 3); self.src_rect.set(w * 3, h * 3, w, h) end end end end #============================================================================== # ■ Game_MapPicture #============================================================================== class Game_MapPicture #-------------------------------------------------------------------------- # ● 公開インスタンス変数 #-------------------------------------------------------------------------- attr_reader :name # ファイル名 attr_reader :x # X 座標 attr_reader :y # Y 座標 attr_reader :zoom_x # X 方向拡大率 attr_reader :zoom_y # Y 方向拡大率 attr_reader :opacity # 不透明度 attr_accessor :current_center # 現在位置がセンター attr_accessor :region_id # リージョンID #-------------------------------------------------------------------------- # ● オブジェクト初期化 # number : ピクチャ番号 #-------------------------------------------------------------------------- def initialize(id) @name = "" @x = 0.0 @y = 0.0 @zoom_x = 100.0 @zoom_y = 100.0 @opacity = 255.0 @duration = 0 @target_x = @x @target_y = @y @target_zoom_x = @zoom_x @target_zoom_y = @zoom_y @target_opacity = @opacity @current_center = false @region_id = id end #-------------------------------------------------------------------------- # ● ピクチャの表示 # name : ファイル名 # x : X 座標 # y : Y 座標 # zoom_x : X 方向拡大率 # zoom_y : Y 方向拡大率 # opacity : 不透明度 # blend_type : ブレンド方法 #-------------------------------------------------------------------------- def show(name, x, y, zoom_x, zoom_y, opacity, blend_type) @name = name @x = x.to_f @y = y.to_f @zoom_x = zoom_x.to_f @zoom_y = zoom_y.to_f @opacity = opacity.to_f @duration = 0 @target_x = @x @target_y = @y @target_zoom_x = @zoom_x @target_zoom_y = @zoom_y @target_opacity = @opacity end #-------------------------------------------------------------------------- # ● ピクチャの移動 # duration : 時間 # x : X 座標 # y : Y 座標 # zoom_x : X 方向拡大率 # zoom_y : Y 方向拡大率 # opacity : 不透明度 # blend_type : ブレンド方法 #-------------------------------------------------------------------------- def move(duration, x, y, zoom_x, zoom_y, opacity, blend_type) @duration = duration @target_x = x.to_f unless @current_center @target_y = y.to_f unless @current_center @target_zoom_x = zoom_x.to_f @target_zoom_y = zoom_y.to_f @target_opacity = opacity.to_f end #-------------------------------------------------------------------------- # ● ピクチャの消去 #-------------------------------------------------------------------------- def erase @name = "" end #-------------------------------------------------------------------------- # ● ピクチャの中央表示 # name : ファイル名 #-------------------------------------------------------------------------- def show_center(name) @name = name @x = center_x @y = center_y @zoom_x = 100.0 @zoom_y = 100.0 @opacity = 255.0 @duration = 0 @target_x = @x @target_y = @y @target_zoom_x = @zoom_x @target_zoom_y = @zoom_y @target_opacity = @opacity end #-------------------------------------------------------------------------- # ● ピクチャの移動 # duration : 時間 #-------------------------------------------------------------------------- def move_center(duration) @duration = duration if duration == 0 @x = center_x @y = center_y end @zoom_x = 100.0 @zoom_y = 100.0 @opacity = 255.0 @target_x = center_x @target_y = center_y @target_zoom_x = @zoom_x @target_zoom_y = @zoom_y @target_opacity = @opacity end #-------------------------------------------------------------------------- # ● ピクチャの中心点X #-------------------------------------------------------------------------- def center_x return (RPG::Cache.picture(@name).width / 2) end #-------------------------------------------------------------------------- # ● ピクチャの中心点Y #-------------------------------------------------------------------------- def center_y return (RPG::Cache.picture(@name).height / 2) end #-------------------------------------------------------------------------- # ● 移動完了? #-------------------------------------------------------------------------- def move_finish? return (@target_x == @x and @target_y == @y and @target_zoom_x == @zoom_x and @target_zoom_y == @zoom_y and @target_opacity == @opacity ) end #-------------------------------------------------------------------------- # ● フレーム更新 #-------------------------------------------------------------------------- def update if @duration >= 1 d = @duration @x = (@x * (d - 1) + @target_x) / d @y = (@y * (d - 1) + @target_y) / d @zoom_x = (@zoom_x * (d - 1) + @target_zoom_x) / d @zoom_y = (@zoom_y * (d - 1) + @target_zoom_y) / d @opacity = (@opacity * (d - 1) + @target_opacity) / d @duration -= 1 end end end #============================================================================== # ■ Sprite_MapPicture #============================================================================== class Sprite_MapPicture < Sprite HALF_W = 320 HALF_H = 240 #-------------------------------------------------------------------------- # ● オブジェクト初期化 # viewport : ビューポート # picture : ピクチャ (Game_MapPicture) #-------------------------------------------------------------------------- def initialize(viewport, picture) super(viewport) @picture = picture @picture_name = "" update end #-------------------------------------------------------------------------- # ● 解放 #-------------------------------------------------------------------------- def dispose if self.bitmap != nil self.bitmap.dispose end super end #-------------------------------------------------------------------------- # ● 地図描画 #-------------------------------------------------------------------------- def draw_map bit = RPG::Cache.picture(@picture_name) # ピクチャグラフィックを取得 self.bitmap = Bitmap.new(bit.width, bit.height) self.bitmap.blt(0, 0, bit, Rect.new(0, 0, bit.width, bit.height)) towns = $game_system.worldmap[@picture.region_id] for id in towns.ids if towns[id].visible and !towns[id].icon.nil? icon = RPG::Cache.icon(towns[id].icon) xx = towns[id].map_pos.x - (icon.width / 2) yy = towns[id].map_pos.y - (icon.height / 2) self.bitmap.blt(xx, yy, icon, Rect.new(0, 0, icon.width, icon.height)) end end end #-------------------------------------------------------------------------- # ● フレーム更新 #-------------------------------------------------------------------------- def update @picture.update # ピクチャのファイル名が現在のものと異なる場合 if @picture_name != @picture.name exe_trans = false if !WorldMap::CHG_MAP_TRAN.nil? and @picture_name != "" exe_trans = true end # ファイル名をインスタンス変数に記憶 @picture_name = @picture.name Graphics.freeze if exe_trans # ファイル名が空でない場合 if @picture_name != "" draw_map # スプライトを可視に設定 self.visible = true end Graphics.transition(40, "Graphics/Transitions/"+WorldMap::CHG_MAP_TRAN) if exe_trans end # ファイル名が空の場合 if @picture_name == "" # スプライトを不可視に設定 self.visible = false return end # 拡大率を設定 self.zoom_x = @picture.zoom_x / 100.0 self.zoom_y = @picture.zoom_y / 100.0 # スプライトの座標を設定 self.x = center_x + (center_x - @picture.x) * self.zoom_x - covert_x self.y = center_y + (center_y - @picture.y) * self.zoom_y - covert_y self.opacity = @picture.opacity # 転送元原点を設定 self.ox = center_x self.oy = center_y end def center_ox end def center_x return (@picture.current_center ? (@picture.x+HALF_W) : (self.bitmap.width/2)) end def center_y return (@picture.current_center ? (@picture.y+HALF_H) : (self.bitmap.height/2)) end def covert_x return center_x - HALF_W end def covert_y return center_y - HALF_H end end