#============================================================================== # ■ VX-RGSS2-28 主人公選択 [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 = "StarlitSky.png" # BGM(RPG::BGM) BGM = RPG::BGM.new("Theme2") # 表示方法 # 0..キャラクター画像 # 1..顔グラフィック画像 TYPE = 0 # 説明文の最大行数 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 Sound.play_decision $scene = Scene_SelectHero.new RPG::BGM.fade(1500) close_command_window Graphics.fadeout(60) Graphics.wait(40) Graphics.frame_count = 0 RPG::BGM.stop 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(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_face 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 = Cache.character(@actor.character_name) sign = @actor.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 n = @actor.character_index self.src_rect.set((n%4*3+1)*cw, (n/4*4)*ch, cw, ch) end #-------------------------------------------------------------------------- # ● 顔グラフィック描画 #-------------------------------------------------------------------------- def draw_face(size=96) self.bitmap = Cache.face(@actor.face_name) x = @actor.face_index % 4 * 96 + (96 - size) / 2 y = @actor.face_index / 4 * 96 + (96 - size) / 2 w = size h = size self.src_rect.set(x, y, w, h) end #-------------------------------------------------------------------------- # ● フレーム更新 #-------------------------------------------------------------------------- def update return if SelectHero::TYPE != 0 @cnt += 1 if (@cnt % 8) == 0 @cnt = 0 if @cnt >= (8 * 4) n = @actor.character_index case (@cnt / 8) when 0; self.src_rect.set((n%4*3+1)*self.w, (n/4*4)*self.h, self.w, self.h) when 1; self.src_rect.set((n%4*3+0)*self.w, (n/4*4)*self.h, self.w, self.h) when 2; self.src_rect.set((n%4*3+1)*self.w, (n/4*4)*self.h, self.w, self.h) when 3; self.src_rect.set((n%4*3+2)*self.w, (n/4*4)*self.h, self.w, self.h) end end end end #============================================================================== # ■ Window_HeroName : 主人公名ウィンドウ #============================================================================== class Window_HeroName < Window_Base #-------------------------------------------------------------------------- # ● オブジェクト初期化 #-------------------------------------------------------------------------- def initialize super(0, 300, 160, WLH/2+32) self.back_opacity = 128 @sprite = Sprite.new @sprite.bitmap = Bitmap.new(width - 32, WLH) @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 * WLH + 32 h += 1 if SelectHero::LINE == 0 super(0, 416-h, 544, 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, WLH, 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 ? 120 : 100 attr_reader :index #-------------------------------------------------------------------------- # ● オブジェクト初期化 #-------------------------------------------------------------------------- def initialize @sprites = [] @ids = SelectHero::HEROES.keys s = @ids.size w = 504 / 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 < Scene_Base T_SELECT = "主人公を選択してください" T_YESNO = "%sを選択しますか?" #-------------------------------------------------------------------------- # ● 開始処理 #-------------------------------------------------------------------------- def start if SelectHero::BACK != nil @back = Sprite.new @back.bitmap = Cache.picture(SelectHero::BACK) end SelectHero::BGM.play # @help_window = Window_Help.new @help_window.set_text(T_SELECT) @characters = SelectHeroes.new # @yn_window = Window_Command.new(140, ["はい", "いいえ"]) @yn_window.x = (544 - 140) / 2 @yn_window.y = 140 @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) Sound.play_cancel @yn_window.active = @yn_window.visible = false @help_window.set_text(T_SELECT) elsif Input.trigger?(Input::C) Sound.play_decision 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) Sound.play_decision @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) Sound.play_cursor @characters.shift_right elsif Input.repeat?(Input::LEFT) Sound.play_cursor @characters.shift_left end end #---------------------------------------------------------------------------- # ● 選択処理 #---------------------------------------------------------------------------- def selection # 選択したアクター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 $scene = Scene_Map.new Graphics.frame_count = 0 RPG::BGM.stop $game_map.autoplay end end