查看: 6106|回复: 10

[已经解决] 如何实现“同一时间只能播放一段音效”的效果?

[复制链接]

梦石
1
星屑
23241
在线时间
9564 小时
注册时间
2012-6-19
回帖
7018

开拓者短篇九导演组冠军

发表于 2013-11-3 11:20:26 | 显示全部楼层 |阅读模式
悬赏2星屑已解决
本帖最后由 喵呜喵5 于 2015-12-29 09:56 编辑

我使用默认的播放SE功能作为游戏的语音功能,每句对话后面都增加一个播放语音的事件
但是,如果玩家按键比较快的话,多段语音会同时播放,明显不科学
目前的做法是把语音做成一段动画,然后对同一个事件播放动画,之前的动画没有播放结束前后一个动画就会被自动忽略

然而感觉用起来还是很麻烦……所以我希望实现“同一时间只能播放一段SE”的效果,前一段SE没有播完之前下一段SE的播放会自动忽略

更进一步,我希望音效A在音效B没有播完之前不能播放但在音效C没有播完之前可以播放,而同时音效D则在音效E播完之前不能播放…………即给音效进行分组,在相同分组中的音效同一时间只能播放一个。
当然,出于方便考虑,我希望这些分组也是动态的,能在游戏中实时的修改。

总之,谢谢大家了(鞠躬)
{:2_253:}




2 年后回来扫自己的旧帖子

这个解决方案其实不错: https://rpg.blue/thread-371224-1-1.html

最佳答案

查看完整内容

本来打算通过system来访问注册表获取音频文件以及拓展名………… 想想还是没有必要 就算可以访问RTP 如果作者忘记打包音频还是没有用 [s]需要自行设置的是一开始的比特率,因为这东西貌似不是固定的……[/s] 改成了设置每个声音的长度 以及音效组@group 可以通过事件来增添列表 你应该看得懂 但是还是解释一下: 简单的测试了一下 应该没有问题 就算有我最近也不能来修…… ...

点评

........看錯了對不起...  发表于 2013-11-3 11:38

百合控

梦石
0
星屑
6548
在线时间
1275 小时
注册时间
2013-8-21
回帖
3522

开拓者

发表于 2013-11-3 11:20:27 | 显示全部楼层
本帖最后由 余烬之中 于 2014-7-25 12:44 编辑

本来打算通过system来访问注册表获取音频文件以及拓展名…………
想想还是没有必要 就算可以访问RTP 如果作者忘记打包音频还是没有用
需要自行设置的是一开始的比特率,因为这东西貌似不是固定的…… 改成了设置每个声音的长度
以及音效组@group
可以通过事件来增添列表 你应该看得懂 但是还是解释一下:
Smomo.segroup(operator, first = nil, second = nil)
这是唯一的操作方法
operator的取值:
  :get
  获取当前的@group,另外两个参数没有意义
  :append
  向first组中新增项second
  :delete
  删除first组中的second
    如果second为nil或false 则删除first整个组
    如果first为nil或false 则删除所有组中的second
    两个都为nil或false 报错没商量
  :init
    调用init方法
  :reset
    调用reset方法
  其他
    报错

简单的测试了一下 应该没有问题 就算有我最近也不能来修……
我是代码以下代码[pre lang="ruby" line="1"]$smomo ||= {}
$smomo["SoundGroup"] = true

#==============================================================================
# ** Smomo::SEGroup
#==============================================================================
module Smomo
module SEGroup
#=============================== settings begin ===============================#
  Supported = %W{ OGG WMA MP3 WAV MID }
                    # append as you like
  Length = {
  # "sound" => length(flame),
    "Absorb1"   => 120,
    "Absorb2"   => 120,
    "Applause1" => 100,
    "Applause2" => 100,
    "Autodoor"  =>  80,
    "Blind"     => 150,
    "Cursor1"   => 100,
    "Cursor2"   => 100,
  }
#================================ settings end ================================#
  module_function
  #--------------------------------------------------------------------------
  # * Initialize SE groups
  #--------------------------------------------------------------------------
  def init
#=============================== settings begin ===============================#
    @group = {
    # group-name => ["sound 1", "sound 2", ...],
      :absorb    => ["Absorb1"  , "Absorb2"  ],
      :applause  => ["Applause1", "Applause2"],
      :group_one => ["Autodoor" , "Blind"    ],
      :cursor    => ["Cursor1"  , "Cursor2"  ],
    }
#================================ settings end ================================#
    reset
  end
  #--------------------------------------------------------------------------
  # * Reset
  #--------------------------------------------------------------------------
  def reset
    @Time = {}
    @group.each_key{|sym| @time[sym] = Time.now}
  end
  #--------------------------------------------------------------------------
  # * OK to play?
  #--------------------------------------------------------------------------
  def check(se)
    return Time.now > @time[se]
  end
  #--------------------------------------------------------------------------
  # * Set the time to end
  #--------------------------------------------------------------------------
  def set_time(file, se)
    raise Errno::ENOENT, "Sound File Must Be In Game Folder!" if no_file? file
    raise Errno::EINVAL, "Must Set The Length!" if !Length[file].is_a? Integer
    @time[se] = Time.now + Length[file] / 60.0
  end
  #--------------------------------------------------------------------------
  # * Sound file in game folder?
  #--------------------------------------------------------------------------
  def no_file?(file)
    file = 'Audio/SE/' + file
    Supported.each{|e| break e if FileTest.exist?(file + "." + e)}.is_a? Array
  end
  #--------------------------------------------------------------------------
  # * Dynamic configuration changes
  #--------------------------------------------------------------------------
  def function(operator, first = nil, second = nil)
    case operator
    when :get
      @group
    when :append
      @group[first].push second
      @group[first].uniq!
    when :delete
      first ? second ? @group[first].delete(second) : @group.delete(first):
      @group.each{|group| group.delete second}
    when :init
      init
    when :reset
      reset
    else
      raise ArgumentError, "Invalid Operator!"
    end
  end
end
  module_function
  #--------------------------------------------------------------------------
  # * Entry
  #--------------------------------------------------------------------------
  def segroup(*args)
    Smomo::SEGroup.function(*args)
  end
end
Smomo.segroup :init
#==============================================================================
# ** RPG::SE
#==============================================================================
class RPG::SE
  #--------------------------------------------------------------------------
  # * Alias method: play
  #--------------------------------------------------------------------------
  alias :mo_segroup_play :play
  def play
    mo_segroup_play if mo_segroup_playOK?
  end
  #--------------------------------------------------------------------------
  # * OK to play?
  #--------------------------------------------------------------------------
  def mo_segroup_playOK?
    current = Smomo.segroup(:get).each do |key, group|
                break key if group.include? @name
              end
    return true if current.is_a? Hash
    Smomo::SEGroup.check(current) &&
    Smomo::SEGroup.set_time(@name, current)
  end
  #--------------------------------------------------------------------------
  # * Alias method: stop
  #--------------------------------------------------------------------------
  class << self
    alias :mo_segroup_stop :stop
    def stop
      mo_segroup_stop
      Smomo::SEGroup.reset
    end
  end
end unless RPG::SE.respond_to? :mo_segroup_stop[/pre]
  

点评

完成了呢\(^0^)/  发表于 2014-7-24 22:12
于是我就耐心的继续等你完善吧……  发表于 2013-11-12 18:07
我收回99%那句话……顶多90%,用于动态改变SE组的Interpreter还没写……  发表于 2013-11-9 19:05
萌新瑟瑟发抖
看到我请叫我去干活
回复

使用道具 举报

梦石
0
星屑
407
在线时间
1291 小时
注册时间
2013-1-12
回帖
3349

贵宾

发表于 2013-11-3 11:27:32 | 显示全部楼层

点评

没错……2V……是我的两倍……足够了  发表于 2013-11-3 11:48
这个不是对话时每显示一个文字播放SE么?我希望实现的是播放人物语音啊……  发表于 2013-11-3 11:32

回复

使用道具 举报

百合控

梦石
0
星屑
6548
在线时间
1275 小时
注册时间
2013-8-21
回帖
3522

开拓者

发表于 2013-11-3 11:38:51 | 显示全部楼层
本帖最后由 余烬之中 于 2013-11-9 19:03 编辑

见11楼

点评

恩.... 就2V  发表于 2013-11-3 11:43

评分

参与人数 1星屑 +60 收起 理由
喵呜喵5 + 60 请加油……

查看全部评分

萌新瑟瑟发抖
看到我请叫我去干活
回复

使用道具 举报

梦石
0
星屑
266
在线时间
2355 小时
注册时间
2009-3-13
回帖
2257

贵宾

发表于 2013-11-3 20:07:54 | 显示全部楼层
你要播放另外的SE之前调用 Audio.se_stop 不就行了。
回复

使用道具 举报

梦石
1
星屑
23241
在线时间
9564 小时
注册时间
2012-6-19
回帖
7018

开拓者短篇九导演组冠军

 楼主| 发表于 2013-11-3 21:00:08 | 显示全部楼层
Sion 发表于 2013-11-3 20:07
你要播放另外的SE之前调用 Audio.se_stop 不就行了。

如果有多段SE同时播出比如角色一边开门一边说话的时候,Audio.se_stop不是连开门的音效也stop了?
回复

使用道具 举报

梦石
0
星屑
266
在线时间
2355 小时
注册时间
2009-3-13
回帖
2257

贵宾

发表于 2013-11-3 21:10:28 | 显示全部楼层
喵呜喵5 发表于 2013-11-3 21:00
如果有多段SE同时播出比如角色一边开门一边说话的时候,Audio.se_stop不是连开门的音效也stop了? ...


能不能不要一边开门一边说话{:2_276:}
  1. sec = File.size("Shape of my heart.mp3") * 8 / 192000
  2. print sec / 60, " ", sec % 60
复制代码
这个代码可以计算出固定比特率(上例是192kbps)的mp3文件时间长度,换算成帧数应用到游戏中就可以了吧。

评分

参与人数 1星屑 +1 收起 理由
无脑之人 + 1 好吐槽

查看全部评分

回复

使用道具 举报

梦石
1
星屑
23241
在线时间
9564 小时
注册时间
2012-6-19
回帖
7018

开拓者短篇九导演组冠军

 楼主| 发表于 2013-11-3 21:41:32 | 显示全部楼层
Sion 发表于 2013-11-3 21:10
能不能不要一边开门一边说话这个代码可以计算出固定比特率(上例是192kbps)的mp3文件时间长度 ...

OGG、WAV格式有类似的代码吗?
SE有没有pos属性?

点评

经过测试wav跟MP3输出是一样的, ogg (与mp3相同码率192kbps,长度4+min)有1秒钟的差异。看起来 RPG::SE 类播放的时候是不记录 pos  发表于 2013-11-3 22:09
根据楼上的方法好像可以完成效果……不过我在学校,是没有时间了  发表于 2013-11-3 21:54
回复

使用道具 举报

梦石
0
星屑
3348
在线时间
1120 小时
注册时间
2009-4-15
回帖
761
发表于 2013-11-3 21:49:04 | 显示全部楼层
本帖最后由 tan12345 于 2013-11-3 21:50 编辑

看了那么久,我才大概理解你的意思……
你想要的是在进行事件过程中,会有各种声音:人物说话声,开门声等等,你需要分组,一组并行播放,一组串行播放(就是上一个完了才可以播放下一个),人物说话声必须是串行播放,而开门声这一类背景声则需要并行播放,不知道理解对不对……

点评

不是串行播放,而是分组之后每一组中同时只有一个声音在播放,播放过程播放该组其他声音的命令会被忽略  发表于 2013-11-3 22:46
回复

使用道具 举报

梦石
0
星屑
803
在线时间
2068 小时
注册时间
2011-10-3
回帖
1620
发表于 2013-11-5 09:50:17 | 显示全部楼层
要不要试试用BGS播放语言,记得BGS是一次只能播放一个?(我没试过,LZ自己去试试吧)
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册会员

本版积分规则

Powered by Discuz! X5.0 © 2001-2026 Discuz! Team.

在本版发帖返回顶部