Ren’Py支持在后台播放音乐和音效,支持的音频文件格式如下:
Opus和Ogg Vorbis格式可能不被某些基于WebKit的浏览器(比如Safari),但对气态平台来说是最好的选择。
Ren’Py支持任意数量的音频通道。有三种一般音频通道是默认定义好的:
music - 音乐播放通道。sound - 音效播放通道。voice - 语音播放通道。通用通道支持音频的播放和音频队列,但同一时间只能播放1个音频文件。可以使用
renpy.music.register_channel() 函数注册新的通用通道。
游戏内自定义配置菜单中的“音乐音量”、“音效音量”和“语音音量”设置的值,会应用于以上对应的音频通道。
另外,除了通用通道,还存在特殊音频通道 audio 。audio通道支持同时播放多个音频文件,但不支持队列播放和中途停止。
音效的用途,包括按钮(button)、菜单选项、图片地图(imagemap)的鼠标悬停和激活状态。详见
按钮样式属性. 两个配置项, config.main_menu_music 和 config.game_menu_music ,分别对应主菜单和游戏菜单播放的音乐。
游戏内播放音乐和音效的常用办法,是使用Ren’Py的三种音乐/音效语句。
play 语句用于播放音效和音乐。如果某个文件正在通过通用通道播放,播放会被中断,并开始播放新的文件。
音频通道名(通常就是“sound”、“music”、“voice”或者“audio”)需要跟在关键词 play 后面。通道名后面是音频文件。音频文件可以是单个文件,也可以是文件列表。如果是文件列表的话,列表内元素顺序播放。
fadein 和 fadeout 分句是可选的。 fadeout指定了正在播放音乐需要停止时的淡出时间,单位为秒。fadein指定了播放新音乐的开头淡入时间。如果没有fadeout时间没有指定,就使用 config.fade_music 的配置值。
loop 和 noloop 分句也是可选的。 loop分句表示音乐循环播放,noloop分句表示音乐只播放一次。如果这两个分句都没有出现,根据通道的默认配置决定实际播放情况。
play music "mozart.ogg"
play sound "woof.mp3"
play myChannel "punch.wav" # 'myChannel'需要先使用renpy.music.register_channel()定义。
"我们也可以播放一个音效或音乐的列表。"
play music [ "a.ogg", "b.ogg" ] fadeout 1.0 fadein 1.0
在audio通道上,同时播放多个音效文件:
play audio "sfx1.opus"
play audio "sfx2.opus"
此处可以使用变量替代字符串。如果某个变量在 音频命名空间 中存在,它就可以在默认的命名空间中直接引用。
play music illurock
Files placed into the audio namespace may automatically define variables that can be used like this.
queue 语句用于组建音频文件队列。当前播放的文件被播放完毕之后,queue语句组建的音频文件队列就会开始播放。
queue语句以关键词 queue 开头,后面跟播放使用的音频通道名。最后是否带 fadein 、 loop 或 noloop 分句是可选的。
queue sound "woof.mp3"
queue music [ "a.ogg", "b.ogg" ]
queue语句也可以使用 volume 从句。
play sound "woof.mp3" volume 0.25
queue sound "woof.mp3" volume 0.5
queue sound "woof.mp3" volume 0.75
queue sound "woof.mp3" volume 1.0
当多个queue语句出现,且没有给任何队列指定互动行为情况下,所有的声音文件都将加入到队列中。 在某个互动行为发生后,第一个queue语句对应的队列将清空,除非其已经被某个play或stop语句清空过。
此处可以使用变量替代字符串。如果某个变量在 音频命名空间 中存在,它就可以在默认的命名空间中直接引用。
使用这些语句的优点是,当lint工具运行时,可以检测出你程序中是否有丢失的音乐音效文件。后面的一些函数允许python接入和控制这些文件,并且会揭示一些高级(却很少用到)的特性。
Ren’Py支持节选播放音频文件。节选播放的语法是,在play语句的文件名之前,加上用英文尖括号<>包含的播放起始点。节选播放规范应该包含成对属性名和属性值,并用空格分隔。
属性值以秒为单位,集成在文件名前面的英文尖括号<>内。三种属性名分别为:
fromtoloopfrom 指定的时间点。)举例:
play music "<from 5 to 15.5>waves.opus"
将从5秒的标记处开始,播放总计10.5秒waves.opus文件内容。下面这条语句:
play music "<loop 6.333>song.opus"
将会在完整播放完文件song.opus后,回到6.333秒标记处重新播放至结尾,并不断循环重复。
某段音频音频的起始播放位置可以同步到另一个音频通道,只需要使用特定的文件名,比如“<sync channelname>track.opus”。 其中channelname就是需要同步的通道名称,可以是music、sound或其他任意注册过的音频通道。
该功能可用于多个循环播放音轨的同步。比如:
play music_2 [ "<sync music_1>layer_2.opus", "layer_2.opus" ]
layer_2.opus播放时将会与music_1通道的循环保持同步,即music_1从头开始播放时也跟随从头播放,而不再会播放完之后再循环。
一段指定时间范围播放静音,格式类似“<silence 3.0>”,其中3.0表示需要的静音持续时间,单位为秒。播放静音用于延迟音效文件的播放点。例如:
play audio [ "<silence .5>", "boom.opus" ]
将播放半秒的静音,然后出现一个爆炸音效。
play 和 queue 语句在音频命名空间内计算入参的值。这意味着可以使用define语句,为音频文件提供一个别名(alias)。
例如,我们可以这样写:
define audio.sunflower = "music/sun-flower-slow-jam.ogg"
然后这样使用:
play music sunflower
Ren’Py会将 game/audio 目录下的文件自动识别为音频文件,并根据文件名在audio命名空间中生成对应变量。
该目录下直接支持的几种音频音频,会被去掉文件扩展名(当前包括.wav、.mp2、.mp3、.ogg和.opus),剩下的文件名强制转为小写字母,并放入audio命名空间。
需要注意,文件名会放入audio命名空间并不表示就会播放。如果需要播放一个名为“opening_song.ogg”文件,需要写:
play music opening_song
某些文件名无法使用这种方式,因为这些文件名不符合Python变量命名规范。例如,“my song.mp3”、“8track.opus”和“this-is-a-song.ogg”就有这种情况。
AudioData(data, filename) link该类会指向一个byte编码对象,包含音频数据。该对象可以传入音频播放系统。包含的音频数据应该是Ren’Py支持的格式(例如RIFF、WAV格式)。
renpy.play(filename, channel=None, **kwargs) link播放一个音效。如果channel为None,默认值为config.play_channel。该函数用在各种样式(style)定义,鼠标悬停声(hover_sound)和激活声(activate_sound)。
renpy.seen_audio(filename) link如果filename对应的音频文件在用户系统中至少被播放过一次,则返回True。
renpy.music.get_duration(channel='music') link返回目前 channel 通道上正在播放的音频或视频文件的全长。若 channel 通道上没有正在播放的文件,则返回0.0。
renpy.music.get_loop(channel=u'music') link返回音频通道上正在循环播放的文件列表,如果没有文件在循环播放则返回None。 如果循环列表还在待播放队列中排队,并没有播放,依然会返回循环列表,而不是正在播放的音乐。
renpy.music.get_pause(channel='music') link返回 channel 通道上的pause标记的值。
renpy.music.get_playing(channel='music') link若入参channel上有音频正在播放,返回文件名。否则返回None。
renpy.music.get_pos(channel='music') link返回入参channel通道上正在播放的音频或者视频文件的已播放进度,单位为秒。如果 channel 通道上没有任何音频或视频文件正在播放,返回None。
由于在某个通道开始播放前,总是会返回None;也可能对应的音频通道已经被静音(mute)。该函数的调用者应该能够处理空值。
renpy.music.is_playing(channel='music') link若入参channel上正在播放一个音频则返回True,否则返回False。或者当声音系统没有工作的情况也返回False。
renpy.music.play(filenames, channel='music', loop=None, fadeout=None, synchro_start=False, fadein=0, tight=None, if_changed=False) link该函数会立即停止入参channel上正在播放的声音,解散音频队列,并开始播放入参filenames指定的文件。
该函数会清空对应通道上所有的pause标记。
renpy.music.queue(filenames, channel='music', loop=None, clear_queue=True, fadein=0, tight=None) link该函数将文件名为filenames的文件加入指定通道channel的播放队列。
该函数会清空对应通道上所有的pause标记。
renpy.music.register_channel(name, mixer=None, loop=None, stop_on_mute=True, tight=False, file_prefix='', file_suffix='', buffer_queue=True, movie=False) link该函数用于注册新的名为入参name的音频通道。之后就可以使用play或queue语句在name通道上播放音频了。
renpy.music.set_pan(pan, delay, channel='music') link设置该通道的声像(pan)。
renpy.music.set_pause(value, channel='music') link将入参value赋值给通道名为channel的暂停标识。若value为True,通道会被暂停,否则正常播放。
renpy.music.set_queue_empty_callback(callback, channel='music') link该函数设置了一个callback函数,当播放队列为空时,将会调用callback函数。播放队列首次变空时callback函数将被调用,且每次会导致播放队列清空的互动行为都会至少调用一次。
callback函数被调用时不带任何参数。其会使用合适的参数调用renpy.music.queue,将声音组件成一个队列。请注意,某个声音在播放时callback就可能会被调用,因为当时待播放队列已经空了。
renpy.music.set_volume(volume, delay=0, channel='music') link设置通道的音量volume。对于控制多个通道的混合器(mixer),该值表示混合器的一个音量分量。 Sets the volume of this channel, as a fraction of the volume of the mixer controlling the channel.
renpy.music.stop(channel='music', fadeout=None) link该函数停止正在播放的音乐,并解散播放队列。如果入参fadeout为None,使用config.fade_music配置值作为淡出效果时间,否则就是用fadeout入参值。
该函数将最后组建的待播放文件列表设置为None。
大多数 renpy.music 函数在 renpy.sound 有别名(alias)。这些函数功能类似,主要差别在于它们默认作用于音效(sound)通道而不是音乐(music)通道,且默认不循环播放。