Project1

标题: 请问这种BGM的播放效果如何实现? [打印本页]

作者: 怪蜀黍    时间: 2011-11-11 09:33
标题: 请问这种BGM的播放效果如何实现?
假设:1、某BGM为非midi格式,或者说它是wma格式;2、BGM由前奏A(0至5秒)和主体B(5至60秒)组成。
问题:怎么实现先播放一次前奏A,接着无间断地重复播放主体B?
通俗地说就是要以下这种伪代码的效果:
  1. begin
  2.   播放0秒至5秒
  3.   loop do
  4.     播放5秒至60秒
  5.   end
  6. end
复制代码
dsu_plus_rewardpost_czw
作者: 月夜神音    时间: 2011-11-11 10:50
本帖最后由 月夜神音 于 2011-11-11 10:52 编辑
  1. # MP3ループ演奏 Ver VX_1.00
  2. # 配布元・サポートURL
  3. # http://members.jcom.home.ne.jp/cogwheel/

  4. #==============================================================================
  5. # ■ RPG
  6. #------------------------------------------------------------------------------
  7. #  RPG全体のモジュールです。
  8. #==============================================================================

  9. module RPG
  10. #==============================================================================
  11. # ■ BGM
  12. #------------------------------------------------------------------------------
  13. #  BGM を管理・制御するクラスです。
  14. #==============================================================================

  15.   class BGM < AudioFile
  16.     @@last = BGM.new
  17.     #--------------------------------------------------------------------------
  18.     # ● BGM の演奏
  19.     #--------------------------------------------------------------------------
  20.     def play
  21.       if @name.empty?
  22.         Audio.bgm_stop
  23.         @@last = BGM.new
  24.       else
  25.         name = "Audio/BGM/"
  26.         start = 0
  27.         loop = 0
  28.         step = [0, 0]
  29.         fin = 0
  30.         case @name
  31.         when "satoc-boss09-2"
  32.           type = "Battle"
  33.           start = 0
  34.           loop = 96040
  35.           fin = 202680
  36.         when "satoc-town07-2"
  37.           type = "Dungeon"
  38.           start = 0
  39.           loop = 31980
  40.           fin = 100000
  41.         else
  42.           type = "Normal"
  43.         end
  44.         if type == "Normal"
  45.           name = @name
  46.         else
  47.           name = $game_audio.name?("Audio/BGM/" + @name)
  48.         end
  49.         $game_audio.bgm_play(name, @volume, @pitch, type, start, loop, fin)
  50.         @@last = self
  51.       end
  52.     end
  53.     #--------------------------------------------------------------------------
  54.     # ● BGM の演奏停止
  55.     #--------------------------------------------------------------------------
  56.     def self.stop
  57.       $game_audio.bgm_stop
  58.       @@last = BGM.new
  59.     end
  60.     #--------------------------------------------------------------------------
  61.     # ● BGM のフェードアウト
  62.     #--------------------------------------------------------------------------
  63.     def self.fade(time)
  64.       $game_audio.fadeout_set(time)
  65.       @@last = BGM.new
  66.     end
  67.   end

  68. #==============================================================================
  69. # ■ ME
  70. #------------------------------------------------------------------------------
  71. #  ME を管理・制御するクラスです。
  72. #==============================================================================

  73.   class ME < AudioFile
  74.     #--------------------------------------------------------------------------
  75.     # ● ME の演奏
  76.     #--------------------------------------------------------------------------
  77.     def play
  78.       if @name.empty?
  79.         Audio.me_stop
  80.       else
  81.         Audio.me_play("Audio/ME/" + @name, @volume, @pitch)
  82.       end
  83.       $game_audio.me_set("Audio/ME/" + @name)
  84.     end
  85.     #--------------------------------------------------------------------------
  86.     # ● ME の演奏停止
  87.     #--------------------------------------------------------------------------
  88.     def self.stop
  89.       Audio.me_stop
  90.       $game_audio.mecount_set(1)
  91.     end
  92.     #--------------------------------------------------------------------------
  93.     # ● ME のフェードアウト
  94.     #--------------------------------------------------------------------------
  95.     def self.fade(time)
  96.       Audio.me_fade(time)
  97.       $game_audio.mecount_set(time * Graphics.frame_rate / 1000)
  98.     end
  99.   end
  100. end

  101. #==============================================================================
  102. # ■ Scene_Map
  103. #------------------------------------------------------------------------------
  104. #  マップ画面の処理を行うクラスです。
  105. #==============================================================================

  106. class Scene_Map < Scene_Base
  107.   #--------------------------------------------------------------------------
  108.   # ● バトル画面への切り替え
  109.   #--------------------------------------------------------------------------
  110.   def call_battle
  111.     @spriteset.update
  112.     Graphics.update
  113.     $game_player.make_encounter_count
  114.     $game_player.straighten
  115.     $game_temp.map_bgm = RPG::BGM.last
  116.     $game_temp.map_bgs = RPG::BGS.last
  117.     # RPG::BGM.stop
  118.     RPG::BGS.stop
  119.     Sound.play_battle_start
  120.     $game_system.battle_bgm.play
  121.     $game_temp.next_scene = nil
  122.     $scene = Scene_Battle.new
  123.   end
  124. end

  125. #==============================================================================
  126. # ■ Game_Audio
  127. #------------------------------------------------------------------------------
  128. #  MP3の演奏・その他BGMの演奏全般を司るクラスです。
  129. # MP3の途中ループ等に対応します。
  130. #==============================================================================

  131. class Game_Audio
  132.   #--------------------------------------------------------------------------
  133.   # ● オブジェクト初期化
  134.   #--------------------------------------------------------------------------
  135.   def initialize
  136.     @play = Win32API.new("winmm.dll", "mciSendString", ["p","p","l","l"], "i")
  137.     @play.call("Close all", "\0" * 255, 255, 0)
  138.     @type = "Normal"
  139.     @me_count = 0
  140.     fadein_set(0)
  141.   end
  142.   #--------------------------------------------------------------------------
  143.   # ● BGM の演奏
  144.   #     name       : BGM ネーム
  145.   #     vol        : ボリューム
  146.   #     pitch      : ピッチ
  147.   #     type       : BGM タイプ
  148.   #     start      : 演奏開始位置
  149.   #     loop       : 演奏ループ時開始位置
  150.   #     fin        : 演奏ループ終了位置
  151.   #--------------------------------------------------------------------------
  152.   def bgm_play(name, vol, pitch, type, start, loop, fin)
  153.     fadein_set(0)
  154.     if type == "Normal"
  155.       bgm_stop(type) if @name != name
  156.       Audio.bgm_play("Audio/BGM/" + name, vol, 100) if name != ""
  157.     elsif @name != name
  158.       bgm_stop(type)
  159.       status = "\0" * 255
  160.       @play.call("Status " + type + " mode", status, 255, 0)
  161.       if status.unpack("A*")[0] == "paused"
  162.         @play.call("Setaudio " + type + " volume to 0", "\0" * 255, 255, 0)
  163.         @play.call("Play " + type, "\0" * 255, 255, 0)
  164.         fadein_set(1000)
  165.       else
  166.         @play.call("Open " + name + " alias " + type + " type MPEGVideo",
  167.           "\0" * 255, 255, 0)
  168.         @play.call("Setaudio " + type + " volume to " +
  169.           (vol ** 2 / 10).to_s, "\0" * 255, 255, 0)
  170.         @play.call("Play " + type + " from " +
  171.           start.to_s + " to " + fin.to_s, "\0" * 255, 255, 0)
  172.       end
  173.       if @me_count > 0
  174.         fadein_set(0)
  175.         @play.call("Setaudio " + type + " volume to 0", "\0" * 255, 255, 0)
  176.       end
  177.     else
  178.       if @me_count > 0
  179.         @play.call("Setaudio " + type + " volume to 0", "\0" * 255, 255, 0)
  180.       else
  181.         @play.call("Setaudio " + type + " volume to " +
  182.           (vol ** 2 / 10).to_s, "\0" * 255, 255, 0)
  183.       end
  184.     end
  185.     @name = name
  186.     @type = type
  187.     @vol = vol
  188.     @start = start
  189.     @loop = loop
  190.     @fin = fin
  191.   end
  192.   #--------------------------------------------------------------------------
  193.   # ● ファイルネームの取得
  194.   #--------------------------------------------------------------------------
  195.   def name?(name)
  196.     if FileTest.exist?(name + ".mp3")
  197.       return (name + ".mp3")
  198.     elsif FileTest.exist?(name + ".ogg")
  199.       return (name + ".ogg")
  200.     elsif FileTest.exist?(name + ".wav")
  201.       return (name + ".wav")
  202.     elsif FileTest.exist?(name + ".mid")
  203.       return (name + ".mid")
  204.     end
  205.     return "name"
  206.   end
  207.   #--------------------------------------------------------------------------
  208.   # ● フェードイン
  209.   #--------------------------------------------------------------------------
  210.   def fadein(time)
  211.     fadein_set(time * 1000)
  212.   end
  213.   #--------------------------------------------------------------------------
  214.   # ● フェードインの設定
  215.   #--------------------------------------------------------------------------
  216.   def fadein_set(time)
  217.     @fade_max = @fade_count = time * Graphics.frame_rate / 1000
  218.   end
  219.   #--------------------------------------------------------------------------
  220.   # ● フェードアウトの設定
  221.   #--------------------------------------------------------------------------
  222.   def fadeout_set(time)
  223.     if @type == "Normal"
  224.       Audio.bgm_fade(time)
  225.     else
  226.       if @fade_count == 0
  227.         @fade_max = time * Graphics.frame_rate / 1000
  228.         @fade_count = - time * Graphics.frame_rate / 1000
  229.       elsif @fade_count > 0
  230.         @fade_max = (time * @fade_max * Graphics.frame_rate) /
  231.           (1000 * (@fade_max - @fade_count))
  232.         @fade_count = - time * Graphics.frame_rate / 1000
  233.       else
  234.         @fade_max = - (time * @fade_max * Graphics.frame_rate) /
  235.           (1000 * @fade_count)
  236.         @fade_count = - time * Graphics.frame_rate / 1000
  237.       end
  238.     end
  239.   end
  240.   #--------------------------------------------------------------------------
  241.   # ● 演奏の停止
  242.   #--------------------------------------------------------------------------
  243.   def bgm_stop(type = "")
  244.     if @type == "Dungeon" and type == "Battle"
  245.       @play.call("Pause " + @type, "\0" * 255, 255, 0)
  246.     else
  247.       if @type == "Normal"
  248.         Audio.bgm_stop
  249.       else
  250.         @play.call("Stop " + @type, "\0" * 255, 255, 0)
  251.         @play.call("Close " + @type, "\0" * 255, 255, 0)
  252.       end
  253.     end
  254.     @type = "Normal"
  255.   end
  256.   #--------------------------------------------------------------------------
  257.   # ● ME 演奏の設定
  258.   #--------------------------------------------------------------------------
  259.   def me_set(name)
  260.     # 現在のBGMが Normal でないのなら
  261.     if @type != "Normal"
  262.       # BGM 演奏の停止
  263.       @play.call("Setaudio " + @type + " volume to 0", "\0" * 255, 255, 0)
  264.     end
  265.     # ME 演奏長の取得
  266.     @play.call("Open " + name?(name) + " alias me type MPEGVideo",
  267.        "\0" * 255, 255, 0)
  268.     length = "\0" * 255
  269.     @play.call("Status me length", length, 255, 0)
  270.     # ME カウントの設定
  271.     @me_count = length.unpack("A*")[0].to_i * 60 / 1000 - 90
  272.   end
  273.   #--------------------------------------------------------------------------
  274.   # ● ME 演奏の直接指定
  275.   #--------------------------------------------------------------------------
  276.   def mecount_set(time)
  277.     @me_count = time
  278.   end
  279.   #--------------------------------------------------------------------------
  280.   # ● フレーム更新
  281.   #--------------------------------------------------------------------------
  282.   def update
  283.     if @type != "Normal"
  284.       code = "\0" * 255
  285.       @play.call("Status " + @type + " position", code, 255, 0)
  286.       if code.unpack("A*")[0].to_i >= @fin
  287.         @play.call("Seek " + @type + " to " + @loop.to_s, "\0" * 255, 255, 0)
  288.         @play.call("Play " + @type + " to " + @fin.to_s, "\0" * 255, 255, 0)
  289.       end
  290.       if @fade_count > 0
  291.         @fade_count -= 1
  292.         @play.call("Setaudio " + @type + " volume to " +
  293.           ((@vol * (@fade_max - @fade_count) / @fade_max) ** 2 / 10).to_s,
  294.           "\0" * 255, 255, 0)
  295.       elsif @fade_count < 0
  296.         @fade_count += 1
  297.         @play.call("Setaudio " + @type + " volume to " +
  298.           ((- @vol * @fade_count / @fade_max) ** 2 / 10).to_s,
  299.           "\0" * 255, 255, 0)
  300.       end
  301.     end
  302.     if @me_count > 0
  303.       @me_count -= 1
  304.       if @type != "Normal" and @me_count == 0
  305.         fadein_set(1000)
  306.       end
  307.     end
  308.   end
  309. end

  310. #==============================================================================
  311. # ■ オーディオクラスの強制作成
  312. #==============================================================================

  313. if $game_audio == nil
  314.   $game_audio = Game_Audio.new
  315. end

  316. #==============================================================================
  317. # ■ Graphics
  318. #------------------------------------------------------------------------------
  319. #  グラフィック全般の処理を行うクラスです。
  320. #==============================================================================

  321. class << Graphics
  322.   #--------------------------------------------------------------------------
  323.   # ● フレーム更新
  324.   #--------------------------------------------------------------------------
  325.   alias :update_audio :update unless method_defined?("update_audio")
  326.   def update
  327.     update_audio
  328.     $game_audio.update
  329.   end
  330. end
复制代码
修改33~55行
when后面为音乐名称,目前好像只对mp3,ogg,wav,mid有效
type为类型,分别是"Normal","Dungeon"和"Battle"
start为开始时音乐桢数
loop为开始循环音乐桢数
fin为结束时音乐桢数
演奏方法是:"start"~"fin"→"loop"~"fin"→"loop"~…持续下去
就这样……
脚本作者:ショウ - 月夜に響くノクターン Rebirth
出处:http://members.jcom.home.ne.jp/cogwheel/
作者: 怪蜀黍    时间: 2011-11-11 14:47
感谢你,问题基本解决了!可是这个脚本有个问题,就是只支持英文或数字名称的BGM,不支持中文名称的BGM。不知道怎么改才能支持中文名称的BGM?




欢迎光临 Project1 (https://rpg.blue/) Powered by Discuz! X3.1