#◆◇◆◇◆ スタッフロールスクリプト ver 1.02 ◇◆◇◆◇ # 全マスタースクリプト共通スクリプト # サポート掲示板 http://www2.ezbbs.net/21/minto-aaa/ # by みんと =begin ■ 更新履歴 ○ ver 1.02(2012/03/04) 条件次第でBGMと同期出来なくなるミスを修正 ○ ver 1.01(2009/06/14) 2度目のスタッフロールが無視されるミスを修正 ○ ver 1.00(2009/03/29) 公開 ■ 説明 スタッフロールの演出に特化したスクリプトです。 スタッフロールは指定した音楽と同期し、 音楽に合わせてスライドします。 音楽が終わると同時にスタッフロールが終了しますので、 間を調節する必要がありません。 ※ 同期演奏できる音楽はwav, mid, mp3に限られます。 oggとファイル名に全角文字と日本語が含まれるファイルも使用できません。 開始するには、 イベントコマンドのスクリプトで ViewData_StaffRoll.start と記入してください。 ■ 対応制御文字 \\i[1] その行の文字を斜体文字にします。 \\y[n] その行を指定した数値分下げます。 設定はソース内部を参照してください。 =end #============================================================================== # ☆ MINTO #------------------------------------------------------------------------------ # 様々なフラグを扱うメインモジュールです。 #============================================================================== module MINTO # スタッフロールスクリプトを有効化 ( true で有効 / false で無効 ) RGSS["スタッフロールスクリプト"] = true end # スタッフロールスクリプトが有効な場合に以降の処理を実行する if MINTO::RGSS["スタッフロールスクリプト"] == true then #============================================================================== # ■ ViewData_StaffRoll #------------------------------------------------------------------------------ #  スタッフロールの処理を行うモジュールです。 # 内部は複数のスプライトで構成されています。 #============================================================================== module ViewData_StaffRoll #-------------------------------------------------------------------------- # ● スタッフロールの取得 #-------------------------------------------------------------------------- def self.set_staff_roll # 演奏するBGM(フォルダ名を含め、フルパスで指定してください) # RTPの曲は必ず"インポート"してください。 # RTPにあってもインポートしていない曲は使えません。 @bgm = "Audio/BGM/051-Positive09.mid" @staff_roll = [] # @staff_roll[インデックス] = 内容 # 空行は自動で間合いを調節します。 # 文章のみの場合は、その文章を中央寄せで表示します @staff_roll[0] = "ぶっひ〜の冒険" @staff_roll[2] = "スタッフ" @staff_roll[4] = "- 声の演出 -" # 配列式の場合は一番左の文章を左側に、それ以外の文章を右側に表示します。 # カテゴリー分けに使用してください。 @staff_roll[5] = ["\\i[1]ぶひっクス", "\\i[1]\\y[32]ぶひ一郎"] @staff_roll[6] = ["\\i[1]スーパーぶひっクス", ""] @staff_roll[7] = ["\\i[1]ぶひっシア", "\\i[1]ぶひ子"] @staff_roll[8] = ["- アクターグラフィック制作 -", "", "\\i[1]ぶひ次郎"] @staff_roll[9] = ["- エネミーグラフィック制作 -", "", "\\i[1]ぶひ三郎"] @staff_roll[10] = ["- エフェクトグラフィック制作 -", "", "\\i[1]ぶひ四郎"] @staff_roll[11] = ["- 背景グラフィック制作 -", "", "\\i[1]ぶひ五郎"] @staff_roll[12] = ["- ドットグラフィック制作 -", "", "\\i[1]ぶひ六郎"] @staff_roll[13] = ["- BGM製作 - ", "", "\\i[1]ぶひ七郎"] @staff_roll[14] = ["- システム作成 -", "", "\\i[1]ぶひ八郎"] @staff_roll[16] = "- フリー素材提供 -" @staff_roll[18] = ["- RGSSスクリプト提供 -", "", "\\i[1]ぶっひ〜のお部屋"] @staff_roll[20] = ["- スペシャルサンクス -", "", "\\i[1]ぶっひ〜", "\\i[1]ぶひにん", "\\i[1]ショッカー戦闘員の皆さん(ウソ)"] @staff_roll[22] = "- 制作 -" @staff_roll[24] = "ぶっひ〜教" end #-------------------------------------------------------------------------- # ● 開始処理 #-------------------------------------------------------------------------- def self.start AudioPass.clear # データ初期化 @y = 32 @index = 0 # ビューポートを作成 @viewport = Viewport.new(0, 0, 640, 480) @viewport.z = 1001 # スプライトを作成 @sprite = Sprite.new @sprite.z = 1002 # ビットマップを作成 @sprite.bitmap = RPG::Cache.picture("END_Back") # メインスプライトを作成 @main_sprite = Sprite.new(@viewport) # スタッフロールを取得 self.set_staff_roll # リフレッシュ self.refresh # 主題歌演奏 AudioPass.bgm_play(@bgm) # 極端な処理落ちを防止する Graphics.frame_reset # メイン処理 self.main # 解放する self.dispose end #-------------------------------------------------------------------------- # ● 解放 #-------------------------------------------------------------------------- def self.dispose # スプライトが無効な場合 if @sprite.nil? or @sprite.disposed? then # メソッドを返す return end # スプライトを解放 @sprite.bitmap.dispose @sprite.bitmap = nil @sprite.dispose @sprite = nil @main_sprite.bitmap.dispose @main_sprite.bitmap = nil @main_sprite.dispose @main_sprite = nil # ビューポートを解放 @viewport.dispose @viewport = nil end #-------------------------------------------------------------------------- # ● 描写Y座標の設定 # code : 描写する文字 #-------------------------------------------------------------------------- def self.draw_y(code) # コードから制御文字を抜き取る code.gsub!(/\\[Yy]\[([0-9]+)\]/) { "" } # 座標を返す return (@y * @index) + $1.to_i end #-------------------------------------------------------------------------- # ● 斜体文字フラグの取得 # code : 描写する文字 #-------------------------------------------------------------------------- def self.italic(code) # コードから制御文字を抜き取る code.gsub!(/\\[Ii]\[([0-9]+)\]/) { "" } # フラグを返す return ($1.to_i == 1) end #-------------------------------------------------------------------------- # ● リフレッシュ #-------------------------------------------------------------------------- def self.refresh @size = 0 # ループ処理 for index in 0...@staff_roll.size do # コード取得 code = @staff_roll[index] # コードに応じて分岐 case code when String then # インデックスを進める @size += 1 when Array then # インデックスを進める @size += code.size else # インデックスを進める @size += 1 end end # ビットマップを作成 @main_sprite.bitmap = Bitmap.new(640, @y * @size) @main_sprite.bitmap.font.size = 22 # ロールを回す @viewport.oy = -480 # ループ処理 for index in 0...@staff_roll.size do # コード取得 code = @staff_roll[index] # コードに応じて分岐 case code when String then # イタリックを設定 @main_sprite.bitmap.font.italic = self.italic(code) # 通常文字として描写(中央寄せ) @main_sprite.bitmap.draw_text(0, draw_y(code), 640, @y, code, 1) when Array then # イタリックを設定 @main_sprite.bitmap.font.italic = self.italic(code[0]) # カテゴリーを描写 @main_sprite.bitmap.draw_text(32, draw_y(code[0]), 320, @y, code[0]) # ループ処理 for sub_index in 1...code.size do # スタッフ名を取得 staff = code[sub_index] # 無効なテキストの場合 if staff.nil? then # 次の候補へ next end # イタリックを設定 @main_sprite.bitmap.font.italic = self.italic(staff) # スタッフ名を描写 @main_sprite.bitmap.draw_text(348, draw_y(staff), 288, @y, staff) # インデックスを進める @index += 1 end end # インデックスを進める @index += 1 end end #-------------------------------------------------------------------------- # ● メイン処理 #-------------------------------------------------------------------------- def self.main # 更新フラグをオン @self_active = true # メインループ処理(更新フラグがオンな限り繰り返す) while @self_active == true do # ゲーム画面を更新 Graphics.update # フレーム更新 self.update end end #-------------------------------------------------------------------------- # ● フレーム更新 #-------------------------------------------------------------------------- def self.update # 残り時間を求める thyme_rate = AudioPass.thyme_rate("エンディング") # ロールを調節する height = @main_sprite.bitmap.height + 480 @viewport.oy = ((height * thyme_rate) / 100.0) - 480 # 音楽の演奏が終了した場合 unless AudioPass.playing?("エンディング") then # 更新フラグをクリア @self_active = false end end end #============================================================================== # ■ Audio #------------------------------------------------------------------------------ #  ミュージック、サウンドにかかわる処理を行うモジュールです。 #============================================================================== module Audio #-------------------------------------------------------------------------- # ● 音楽の解放 #-------------------------------------------------------------------------- def self.dispose self.bgs_stop self.me_stop self.bgm_stop end end #============================================================================== # ☆ AudioPass #------------------------------------------------------------------------------ # 指定されたBGMを実際のBGMに変換して演奏するモジュールです。 # wav、mp3にサポートしています。 #============================================================================== module AudioPass if @audio != nil self.dispose @audio = nil end @audio = Win32API.new("winmm.dll", "mciSendString", ["p","p","l","l"], "i") @last_bgm = "" @type = 0 @active_device = "エンディング" @devices = ["エンディング"] @bgm = {} #-------------------------------------------------------------------------- # ● 音楽ファイルの解放 #-------------------------------------------------------------------------- def self.dispose @audio.call("Close all ", "\0" * 255, 255, 0) @active_device = "" @devices = [] @bgm = {} end #-------------------------------------------------------------------------- # ● 音楽ファイルの停止 # device : 要求されたデバイス #-------------------------------------------------------------------------- def self.clear(device = @active_device) # 指定されたデバイスを解放 @audio.call("Close " + device, "\0" * 255, 255, 0) # 演奏中のBGM名をクリア @bgm[device] = nil # 実行デバイス数が2以上の場合 if @devices.size >= 2 then # デバイスを詰める @devices.shift # 新しいデバイスを設定 @active_device = @devices[0].to_s.dup end end #-------------------------------------------------------------------------- # ● 音楽ファイルを実行する # bgm : BGMファイル名 # volume : 音量 # device : 要求されたデバイス #-------------------------------------------------------------------------- def self.bgm_play(bgm, device = "エンディング") # オーディオを解放 Audio.dispose # 前回と同じ音楽の場合 if @bgm[device] == bgm then # メソッドを返す return # 前回と異なる音楽の場合 else # 音楽を解放 self.clear(device) end # 求められたデバイスを先頭に移動 @devices.delete(device) @devices.unshift(device) # アクティブデバイスにシフト @active_device = @devices[0] # MIDIフラグの取得 @midi = (bgm.include?(".mid")) # MIDIの場合 if @midi == true then # 音楽を開くためのコマンドを設定(MIDI) open = "Open " + bgm + " alias " + device + " type mpegvideo" # MIDI以外の場合 else # 音楽を開くためのコマンドを設定(通常) open = "Open " + bgm + " alias " + device + " type MPEGVideo" end # 音楽を演奏するためのコマンドを設定 play = "Play " + device # 指定した音楽ファイルを開く @audio.call(open, "\0" * 255, 255, 0) # MIDIの場合 if @midi == true then # ボリュームを設定(ダミー演奏) vol = "Setaudio " + device + " volume to 0" @audio.call(vol, "\0" * 255, 255, 0) # MEとして通常演奏 Audio.me_play(bgm, 100, 100) end # 指定した音楽ファイルを演奏する @audio.call(play, "\0" * 255, 255, 0) # 音楽を保存 @bgm[device] = bgm.dup end #-------------------------------------------------------------------------- # ● ボイスの残り時間の取得 # device : 要求されたデバイス #-------------------------------------------------------------------------- def self.thyme_rate(device = @active_device) # 演奏中でない場合 unless self.playing?(device) then # メソッドを返す return 0 end # 長さから演奏位置を引く return (self.position(device).to_i * 100 / self.length(device).to_i.to_f) end #-------------------------------------------------------------------------- # ● 音楽の長さの取得 # device : 要求されたデバイス #-------------------------------------------------------------------------- def self.length(device = @active_device) buf = "\0" * 255 @audio.call("Status " + device + " length", buf, 255, 0) return buf.unpack("A*")[0] end #-------------------------------------------------------------------------- # ● 音楽の演奏位置の取得 # device : 要求されたデバイス #-------------------------------------------------------------------------- def self.position(device = @active_device) buf = "\0" * 255 @audio.call("Status " + device + " position", buf, 255, 0) return buf.unpack("A*")[0] end #-------------------------------------------------------------------------- # ● 音楽状態の取得 # device : 要求されたデバイス #-------------------------------------------------------------------------- def self.status(device = @active_device) buf = "\0" * 255 @audio.call("Status " + device + " mode", buf, 255, 0) return buf.unpack("A*")[0] end #-------------------------------------------------------------------------- # ● 音楽演奏中フラグの取得 # device : 要求されたデバイス #-------------------------------------------------------------------------- def self.playing?(device = @active_device) self.status(device) == "playing" end #-------------------------------------------------------------------------- # ● 音楽停止中フラグの取得 # device : 要求されたデバイス #-------------------------------------------------------------------------- def self.pause?(device = @active_device) self.status(device) == "paused" end end end