#============================================================================== # ■ XP-RGSS-73 主人公選択 [Ver.1.0.0] by Claimh #------------------------------------------------------------------------------ # オープニング前などに主人公を選択します。 # 選択したアクターIDは $game_system.hero_id で参照できます。 #------------------------------------------------------------------------------ #[ オープンングで選択させるには ] # Scene_Title#command_new_game の中などで # $scene = Scene_SelectHero.new # に呼ぶように変更しておいて下さい。 #------------------------------------------------------------------------------ #[ 説明文で使用できる制御文字 ] # \\c[n] : 文字色変更 # \\+ : ボールド表示 開始/終了 # \\- : イタリック表示 開始/終了 # \\x[n] : X軸方向 n の場所から描画 # \\n : 改行 #============================================================================== #============================================================================== # ■ StartPos : 開始位置 #============================================================================== module SelectHero class StartPos attr_reader :map_id attr_reader :x attr_reader :y attr_reader :actors #-------------------------------------------------------------------------- # ● オブジェクト初期化 # map_id : マップID # x : 開始位置X # y : 開始位置Y # actors : 初期メンバーのアクターIDs #-------------------------------------------------------------------------- def initialize(map_id, x=0, y=0, actors=[]) @map_id = map_id; @x = x; @y = y; @actors = actors end end end #============================================================================== # ■ 設定 #============================================================================== module SelectHero # 背景(Graphics/Pictures) BACK = "050-DarkSpace01.jpg" # BGM(RPG::AudioFile) BGM = RPG::AudioFile.new("013-Theme02") # 表示方法 # 0..キャラクター画像 # 1..バトラー画像 TYPE = 1 # 説明文の最大行数 LINE = 4 # 主人公設定 HEROES = { # アクターID => [開始位置(StartPos), 説明文] 1 => [StartPos.new(1, 10, 10, [1,7,8]), "主人公1説明\\n\\c[1]説明文\\c[0]\\n\\+テスト\\+\\n"\ "ABC" ], 2 => [StartPos.new(2, 8, 7, [2]), "主人公2説明\\n\\c[2]説明文\\c[0]\\n\\-テスト\\-" ], 4 => [StartPos.new(3, 2, 8, [4,5]), "主人公3説明\\n\\c[3]説明文\\c[0]\\n\\-\\+テスト\\+\\-" ], } end #=begin # Scene_Title変更例 class Scene_Title #-------------------------------------------------------------------------- # ● コマンド : ニューゲーム #-------------------------------------------------------------------------- def command_new_game # 決定 SE を演奏 $game_system.se_play($data_system.decision_se) # BGM を停止 Audio.bgm_stop # 主人公選択へ $scene = Scene_SelectHero.new end end #=end #============================================================================== # ■ Game_System #============================================================================== class Game_System #-------------------------------------------------------------------------- # ● 公開インスタンス変数 #-------------------------------------------------------------------------- attr_accessor :hero_id # 主人公のアクターID #-------------------------------------------------------------------------- # ● オブジェクト初期化 #-------------------------------------------------------------------------- alias initialize_hero initialize def initialize initialize_hero @hero_id = 0 end end #============================================================================== # ■ Game_Party #============================================================================== class Game_Party #-------------------------------------------------------------------------- # ● 初期パーティのセットアップ [再定義] #-------------------------------------------------------------------------- alias setup_starting_members_hero setup_starting_members def setup_starting_members if $game_system.hero_id == 0 setup_starting_members_hero else @actors = [] for i in SelectHero::HEROES[$game_system.hero_id][0].actors @actors.push($game_actors[i]) end end end end #============================================================================== # ■ Window_Hero : 主人公表示ウィンドウ #============================================================================== class Window_Hero < Sprite attr_reader :index #-------------------------------------------------------------------------- # ● オブジェクト初期化 #-------------------------------------------------------------------------- def initialize(actor_id, i) super(nil) @actor = $data_actors[actor_id] @index = i case SelectHero::TYPE when 0; draw_character when 1; draw_battler end refresh(i == 0) end #-------------------------------------------------------------------------- # ● 主人公名 #-------------------------------------------------------------------------- def name return @actor.name end #-------------------------------------------------------------------------- # ● 高さ #-------------------------------------------------------------------------- def h return self.src_rect.height end #-------------------------------------------------------------------------- # ● 幅 #-------------------------------------------------------------------------- def w return self.src_rect.width end #-------------------------------------------------------------------------- # ● リフレッシュ #-------------------------------------------------------------------------- def refresh(active=false) self.opacity = active ? 255 : 100 @cnt = -1 update end #-------------------------------------------------------------------------- # ● キャラクター描画 #-------------------------------------------------------------------------- def draw_character self.bitmap = RPG::Cache.character(@actor.character_name, @actor.character_hue) self.src_rect.set(0, 0, self.bitmap.width / 4, self.bitmap.height / 4) end #-------------------------------------------------------------------------- # ● バトラー描画 #-------------------------------------------------------------------------- def draw_battler self.bitmap = RPG::Cache.battler(@actor.battler_name, @actor.battler_hue) end #-------------------------------------------------------------------------- # ● フレーム更新 #-------------------------------------------------------------------------- def update return if SelectHero::TYPE != 0 @cnt += 1 if (@cnt % 8) == 0 @cnt = 0 if @cnt >= (8 * 4) self.src_rect.set(self.w * (@cnt / 8), 0, self.w, self.h) end end end #============================================================================== # ■ Window_HeroName : 主人公名ウィンドウ #============================================================================== class Window_HeroName < Window_Base #-------------------------------------------------------------------------- # ● オブジェクト初期化 #-------------------------------------------------------------------------- def initialize super(0, 300, 200, 16+32) self.back_opacity = 128 @sprite = Sprite.new @sprite.bitmap = Bitmap.new(width - 32, 32) @sprite.z = self.z + 10 end #-------------------------------------------------------------------------- # ● オブジェクト解放 #-------------------------------------------------------------------------- def dispose super @sprite.dispose end #-------------------------------------------------------------------------- # ● リフレッシュ #-------------------------------------------------------------------------- def refresh(x, y, name) y = 260 if y > 260 self.x = x self.y = y @sprite.bitmap.clear @sprite.x = x + 8 @sprite.y = y + 8 @sprite.bitmap.draw_text(0, 0, @sprite.bitmap.width, @sprite.bitmap.height, name, 1) end end #============================================================================== # ■ Window_HeroInfo : 主人公情報ウィンドウ #============================================================================== class Window_HeroInfo < Window_Base #-------------------------------------------------------------------------- # ● オブジェクト初期化 #-------------------------------------------------------------------------- def initialize h = SelectHero::LINE * 32 + 32 h += 1 if SelectHero::LINE == 0 super(0, 480-h, 640, h) self.visible = false if SelectHero::LINE == 0 self.contents = Bitmap.new(width - 32, height - 32) end #-------------------------------------------------------------------------- # ● リフレッシュ #-------------------------------------------------------------------------- def refresh(i=0) self.contents.clear draw_info_text(0, 0, self.contents.width, 32, SelectHero::HEROES[i][1]) end #-------------------------------------------------------------------------- # ● 情報の描画 #-------------------------------------------------------------------------- def draw_info_text(x, y, w, text_h, txt) txt = "" if txt.nil? text = txt.dup xx = 0 line = 0 # 便宜上 text.gsub!(/\\\\/) { "\000" } # \\c[n] : 文字色変更 text.gsub!(/\\[Cc]\[([0-9]+)\]/) { "\001[#{$1}]" } # \\+ : ボールド表示 開始/終了 text.gsub!(/\\[+]/) { "\002" } # \\- : イタリック表示 開始/終了 text.gsub!(/\\[-]/) { "\003" } # \\x[n] : X軸方向 n の場所から描画 text.gsub!(/\\[Xx]\[([0-9]+)\]/) { "\004[#{$1}]" } # \\n : 改行 text.gsub!(/\\[Nn]/) { "\005" } while ((c = text.slice!(/./m)) != nil) break if SelectHero::LINE <= line # \\ の場合、本来の文字に戻す c = "\\" if c == "\000" # \\c[n] : 文字色変更 if c == "\001" # 文字色を変更 text.sub!(/\[([0-9]+)\]/, "") self.contents.font.color = text_color($1.to_i) next # 次の文字へ end # \\+ : ボールド表示 開始/終了 if c == "\002" self.contents.font.bold = !self.contents.font.bold next # 次の文字へ end # \\- : イタリック表示 開始/終了 if c == "\003" self.contents.font.italic = !self.contents.font.italic next # 次の文字へ end if c == "\004" # 描画位置を変更 text.sub!(/\[([0-9]+)\]/, "") xx = $1.to_i next # 次の文字へ end # \\n : 改行 if c == "\005" xx = 0; y += text_h; line += 1 next # 次の文字へ end # 文字を描画 self.contents.draw_text(x+xx, y, 40, text_h, c) # x に描画した文字の幅を加算 xx += self.contents.text_size(c).width # 自動改行 if xx > w xx = 0; y += text_h; line += 1 end end end end #============================================================================== # ■ SelectHeroes : 主人公選択 #============================================================================== class SelectHeroes OFFSET = SelectHero::TYPE == 0 ? 140 : 70 attr_reader :index #-------------------------------------------------------------------------- # ● オブジェクト初期化 #-------------------------------------------------------------------------- def initialize @sprites = [] @ids = SelectHero::HEROES.keys s = @ids.size w = 600 / s @h = 100 for i in 0...s @sprites.push(Window_Hero.new(@ids[i], i)) @h = @sprites[i].h if @h < @sprites[i].h end for i in 0...s @sprites[i].x = 20 + w * i + (w - @sprites[i].w) / 2 @sprites[i].y = OFFSET + (@h - @sprites[i].h) / 2 end @index = 0 @window = Window_HeroInfo.new @name = Window_HeroName.new refresh end #-------------------------------------------------------------------------- # ● オブジェクト解放 #-------------------------------------------------------------------------- def dispose for s in @sprites s.dispose end @window.dispose @name.dispose end #-------------------------------------------------------------------------- # ● アクターID #-------------------------------------------------------------------------- def actor_id return @ids[@index] end #-------------------------------------------------------------------------- # ● アクター名 #-------------------------------------------------------------------------- def name return @sprites[@index].name end #-------------------------------------------------------------------------- # ● アクターID #-------------------------------------------------------------------------- def start return SelectHero::HEROES[self.actor_id][0] end #-------------------------------------------------------------------------- # ● 右シフト #-------------------------------------------------------------------------- def shift_right @index = (@index + 1) % @sprites.size refresh end #-------------------------------------------------------------------------- # ● 左シフト #-------------------------------------------------------------------------- def shift_left @index = (@index - 1 + @sprites.size) % @sprites.size refresh end #-------------------------------------------------------------------------- # ● リフレッシュ #-------------------------------------------------------------------------- def refresh for s in @sprites if s.index == @index s.refresh(true) @window.refresh(self.actor_id) x = s.x + (s.w - @name.width) / 2 @name.refresh(x, OFFSET+@h, s.name) else s.refresh(false) end end end #-------------------------------------------------------------------------- # ● フレーム更新 #-------------------------------------------------------------------------- def update for s in @sprites s.update if s.index == @index end end end #============================================================================== # ■ Scene_SelectHero : 主人公選択シーン #============================================================================== class Scene_SelectHero T_SELECT = "主人公を選択してください" T_YESNO = "%sを選択しますか?" #-------------------------------------------------------------------------- # ● メイン処理 #-------------------------------------------------------------------------- def main start # 開始処理 Graphics.transition # トランジション実行 loop do Graphics.update # ゲーム画面を更新 Input.update # 入力情報を更新 update # フレーム更新 break if $scene != self # 画面が切り替わったらループを中断 end Graphics.update Graphics.freeze # トランジション準備 terminate # 終了処理 end #-------------------------------------------------------------------------- # ● 開始処理 #-------------------------------------------------------------------------- def start if SelectHero::BACK != nil @back = Sprite.new @back.bitmap = RPG::Cache.picture(SelectHero::BACK) end $game_system.bgm_play(SelectHero::BGM) # @help_window = Window_Help.new @help_window.set_text(T_SELECT) @characters = SelectHeroes.new # @yn_window = Window_Command.new(160, ["はい", "いいえ"]) @yn_window.x = (640 - 160) / 2 @yn_window.y = 160 @yn_window.active = @yn_window.visible = false end #-------------------------------------------------------------------------- # ● 終了処理 #-------------------------------------------------------------------------- def terminate @back.dispose if SelectHero::BACK != nil @characters.dispose @help_window.dispose @yn_window.dispose end #---------------------------------------------------------------------------- # ● フレーム更新 #---------------------------------------------------------------------------- def update if @yn_window.active @yn_window.update if Input.trigger?(Input::B) $game_system.se_play($data_system.cancel_se) @yn_window.active = @yn_window.visible = false @help_window.set_text(T_SELECT) elsif Input.trigger?(Input::C) $game_system.se_play($data_system.decision_se) case @yn_window.index when 0; selection when 1; @yn_window.active = @yn_window.visible = false @help_window.set_text(T_SELECT) end end else update_select end @characters.update end #---------------------------------------------------------------------------- # ● フレーム更新 #---------------------------------------------------------------------------- def update_select if Input.trigger?(Input::C) $game_system.se_play($data_system.decision_se) @yn_window.active = @yn_window.visible = true @yn_window.index = 1 @help_window.set_text(sprintf(T_YESNO, @characters.name)) elsif Input.repeat?(Input::RIGHT) $game_system.se_play($data_system.cursor_se) @characters.shift_right elsif Input.repeat?(Input::LEFT) $game_system.se_play($data_system.cursor_se) @characters.shift_left end end #---------------------------------------------------------------------------- # ● 選択処理 #---------------------------------------------------------------------------- def selection # BGM を停止 Audio.bgm_stop # プレイ時間計測用のフレームカウントをリセット Graphics.frame_count = 0 # 各種ゲームオブジェクトを作成 $game_temp = Game_Temp.new $game_system = Game_System.new $game_switches = Game_Switches.new $game_variables = Game_Variables.new $game_self_switches = Game_SelfSwitches.new $game_screen = Game_Screen.new $game_actors = Game_Actors.new $game_party = Game_Party.new $game_troop = Game_Troop.new $game_map = Game_Map.new $game_player = Game_Player.new # 選択したアクターIDを入れる $game_system.hero_id = @characters.actor_id # 初期パーティをセットアップ $game_party.setup_starting_members # 初期位置のマップをセットアップ $game_map.setup(@characters.start.map_id) # プレイヤーを初期位置に移動 $game_player.moveto(@characters.start.x, @characters.start.y) # プレイヤーをリフレッシュ $game_player.refresh # マップに設定されている BGM と BGS の自動切り替えを実行 $game_map.autoplay # マップを更新 (並列イベント実行) $game_map.update # マップ画面に切り替え $scene = Scene_Map.new end end