音频 link
Ren’Py支持在后台播放音乐和音效,支持的音频文件格式如下:
Opus
Ogg Vorbis
MP3
MP2
FLAC
WAV (未压缩的有符号16bit型PCM编码格式)
在Web浏览器上,Ren’Py会检查一个音频格式列表,并根据浏览器支持的格式启用一个更快更少卡顿的模式。
如果你的游戏只是用mp3,而且不考虑Safari浏览器,可以直接修改 config.webaudio_required_types
的值。
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语句 link
play
语句用于播放音效和音乐。如果某个文件正在通过通用通道播放,播放会被中断,并开始播放新的文件。
音频通道名(通常就是“sound”、“music”、“voice”或者“audio”)需要跟在关键词 play
后面。通道名后面是音频文件。音频文件可以是单个文件,也可以是文件列表。如果是文件列表的话,列表内元素顺序播放。
fadein
和 fadeout
分句是可选的。 fadeout指定了正在播放音乐需要停止时的淡出时间,单位为秒。fadein指定了播放新音乐的开头淡入时间。如果没有fadeout时间没有指定,就使用 config.fadeout_audio
的配置值。
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
当提供了 if_changed
从句,并且对应的音频通道正在播放,播放指令不会中断当前播放的音频。
label market_side:
play music market
"我们正在进入市场。"
jump market_main
label market_main:
play music market if_changed
"我们可能刚进入市场,也可能已经在市场里一段时间了。"
"如果我们已经在市场里一段时间了,音乐不会停止并重从播放,只是继续播放。"
jump market_main
volume
从句也是可选的,可以指定音量值,音量范围为0.0到1.0。
这样每次指定音频文件时,也可以同时设置音量。
play sound "woof.mp3" volume 0.5
在audio通道上,同时播放多个音效文件:
play audio "sfx1.opus"
play audio "sfx2.opus"
此处可以使用变量替代字符串。如果某个变量在 音频命名空间 中存在,它就可以在默认的命名空间中直接引用。
play music illurock
放入audio命名空间的文件会根据文件名自动定义变量并使用。
stop语句 link
stop语句以关键词 stop
开头,后面跟需要静音的音频通道名。最后有一个可选的 fadeout
分句。
如果没有fadeout时间没有指定,就使用 config.fadeout_audio
的配置值。
stop sound
stop music fadeout 1.0
queue语句 link
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语句清空过。
此处可以使用变量替代字符串。如果某个变量在 音频命名空间 中存在,它就可以在默认的命名空间中直接引用:
define audio.woof = "woof.mp3"
# ...
play sound woof
使用这些语句的优点是,当lint工具运行时,可以检测出你程序中是否有丢失的音乐音效文件。后面的一些函数允许python接入和控制这些文件,并且会揭示一些高级(却很少用到)的特性。
节选播放 link
Ren’Py支持节选播放音频文件。节选播放的语法是,在play语句的文件名之前,加上用英文尖括号<>包含的播放起始点。节选播放规范应该包含成对属性名和属性值,并用空格分隔。
属性值以秒为单位,集成在文件名前面的英文尖括号<>内。三种属性名分别为:
from
指定播放文件的起始时间点。(默认值为0.0秒)
to
指定播放文件的终止时间点。(默认值为文件结束。)
loop
指定需要循环播放的文件起始和终止时间点。(默认的起始时间点为文件开头或
from
指定的时间点。)
举例:
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秒标记处重新播放至结尾,并不断循环重复。
同步起始位置 link
某段音频音频的起始播放位置可以同步到另一个音频通道,只需要使用特定的文件名,比如“<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从头开始播放时也跟随从头播放,而不再会播放完之后再循环。
音量 link
播放音频时的音量与以下变量都有关:
混音器“main”的音量值
相关音频通道的混音器音量值
音频通道的音量值
音频自身音量
以上4项音量值都介于0与1之间,最终音量值是它们相乘后的结果。
例如,main音量值80%(0.8),混音器音量值100%,音频通道音量值50%(0.5),音频自身音量25%(0.25)。 最终音量为 .8*1.*.5*.25 = .1,即10% 。
混音器音量可以使用 preferences.set_mixer()
函数、SetMixer()
行为和 Preference()
行为指定 "mixer <mixer> volume"
进行设置。
audio和sound音频通道相关的混音器为“sfx”,music音频通道相关的混音器为“music”,而voice音频通道相关的混音器为“voice”。
每个音频通道都与“main”混音器相关。
使用 renpy.music.set_volume()
函数可以设置某个音频通道的音量。
通常仅当多个音频通道共用同一混音器时才需要用。
renpy.music.register_channel()
函数的 mixer
参数可以在注册音频通道时指定关联的混音器,如果混音器不存在则直接创建一个。
在 play语句 后面加 volume
从句可以直接设置音频文件的相对音量。
除了音量值,各音频通道关联的混音器都有静音标识。
启用静音标识后,会将音量直接设置为0.
可以使用 SetMute()
、ToggleMute()
、Preference()
或 preferences.set_mute()
,指定“mixer <mixer> mute”启用对应混音器的静音标识。
播放静音 link
一段指定时间范围播放静音,格式类似“<silence 3.0>”,其中3.0表示需要的静音持续时间,单位为秒。播放静音用于延迟音效文件的播放点。例如:
play audio [ "<silence .5>", "boom.opus" ]
将播放半秒的静音,然后出现一个爆炸音效。
音频命名空间和目录 link
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”就有这种情况。
Ren’Py搜索音频文件时,如果在game目录中没有对应的匹配文件,会再次在audio目录中寻找。 例如:
play music "opening.ogg"
Will first look for game/opening.ogg
. If not found, Ren’Py will look for
game/audio/opening.ogg
.
会先寻找 game/opening.ogg
。若未果则会寻找 game/audio/opening.ogg
。
行为函数 link
详见 音频行为。
相关函数 link
- AudioData(data, filename) link
该类会指向一个byte编码对象,包含音频数据。该对象可以传入音频播放系统。包含的音频数据应该是Ren’Py支持的格式(例如RIFF、WAV格式)。
- data
包含音频文件数据的byte编码对象。
- filename
与音频数据相关的复合文件名。它可以表示音频数据格式,也可以用做报错信息。
- renpy.mark_audio_seen(filename) link
将指定文件名的文件标记为当前用户已播放过至少一次。
- renpy.mark_audio_unseen(filename) link
将指定文件名的文件标记为当前用户未播放过。
- 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='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指定的文件。
- filenames
该值可以是单个文件,也可以是待播放的文件列表。
- channel
播放声音使用的通道。
- loop
若该值为True,音轨会循环播放,前提是其已经是播放队列最后一个音频。
- fadeout
若不为空,这是一个淡出效果的持续时间,单位为秒。否则,淡出时间使用config.fade_music的值。
- synchro_start
Ren’Py会确保所有synchro_start标志为True的通道,能够在几乎同一时间一齐开始播放音频。当我们需要两个音频文件相互同步时,synchro_start就应该被设置为True。
- fadein
音频开始淡入效果持续时间,单位为秒,在循环播放时仅对第一遍播放有效。
- tight
若该值为True,淡出效果将作用至同一个队列中后面的声音。若为空,当loop为True时tight也为True,否则为False。
- if_changed
若该值为True,当前真在播放的音频不会被立刻停止/淡出,而会继续播放。
- relative_volume
当前音频通道播放音频时的相对音量值。 指定文件将以该音量值播放。 如果没有指定该音量值则默认为1.0,表示以音频文件原始音量播放,再乘以混音器、音频通道和相关第二音量的值。
该函数会清空对应通道上所有的pause标记。
- renpy.music.pump() link
“pump”是指对音频系统的操作。 通常来说,使用
play
、queue
和stop
语句及等效函数后,会在下次互动时才正式生效。 在某些情况下,多个语句之间会互相取消。例如,play语句后面跟随一个stop从句,会使得音频无法播放。如果在play和stop语句之间调用该函数,音频会该函数返回结果前播放音频,并随后淡出。
play music "mytrack.opus" $ renpy.music.pump() stop music fadeout 4
- renpy.music.queue(filenames, channel='music', loop=None, clear_queue=True, fadein=0, tight=None) link
该函数将文件名为filenames的文件加入指定通道channel的播放队列。
- filenames
该值可以是单个文件,也可以是待播放的文件列表。
- channel
播放声音使用的通道。
- loop
若该值为True,音轨会循环播放,前提是其已经是播放队列最后一个音频。
- clear_queue
若为True,当前播放文件结束后,播放队列中原有文件将被清空。若为False,新增文件会被加在原有队列结尾。无论实际哪种情况,如果当前没有任何音频正在播放,新队列中的音频都会立刻被播放。
- fadein
音频开始淡入效果持续时间,单位为秒,在循环播放时仅对第一遍播放有效。
- tight
若该值为True,淡出效果将作用至同一个队列中后面的声音。若为空,当loop为True时tight也为True,否则为False。
- relative_volume
当前音频通道播放音频时的相对音量值。 指定文件将以该音量值播放。 如果没有指定该音量值则默认为1.0,表示以音频文件原始音量播放,再乘以混音器、音频通道和相关第二音量的值。
该函数会清空对应通道上所有的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通道上播放音频了。
- name
待注册音频通道名。
- mixer
混合器(mixer)使用的通道名。默认情况下,Ren’Py能识别“music”、“sfx”和“voice”混合器。使用其他名称也是可行的,不过可能要修改个性化界面。
- loop
若为True,在新注册通道上的音频默认循环播放。
- stop_on_mute
若为True,当新注册通道被静音(mute)时,通道上所有音频都会停止播放。
- tight
若为True,即使有淡出效果,依然可以循环播放。若要实现音效、音乐的无缝连接,就应该把这项设为True。若使用音乐的淡出效果则设置为False。
- file_prefix
在该通道上播放的所有声音文件都会添加的文件名前缀。
- file_suffix
在该通道上播放的所有声音文件都会添加的文件名后缀。
- buffer_queue
我们是否应缓存一两个文件或者一个文件队列?如果通道是播放音频的话应该设置为True,如果播放视频的话应该设置为False。
- movie
若值为True,该通道会被设为播放视频。
- framedrop
该参数控制视频卡顿时的处理方式。若为True,则会跳帧以保持音视频同步。若为False,Ren’Py会无视视频迟延。
- renpy.music.set_pan(pan, delay, channel='music') link
设置该通道的声像(pan)。
- pan
控制音频的音源位置的一个值,位于-1至1的闭区间内。若该值为-1,所有音频使用左声道。若该值为0,左右声道均衡发声。若该值为1,所有音频使用右声道。
- delay
为了形成声像使用的延迟时间。
- channel
应用声像的通道名。可以是音乐或音效通道。通常使用通道7,也就是默认的音乐通道。
- 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.
- volume
该值位于0.0至1.0的闭合区间。对于控制多个通道的混合器(mixer),该值表示混合器的一个音量分量。
- delay
该值代表一个时间量,用于新旧音量值切换/平滑过渡时的时延,单位为秒。该值会保存在存档中,并接受回滚操作。
- channel
需要设置的通道名。
- renpy.music.stop(channel='music', fadeout=None) link
该函数停止正在播放的音乐,并解散播放队列。如果入参fadeout为None,使用config.fade_music配置值作为淡出效果时间,否则就是用fadeout入参值。
该函数将最后组建的待播放文件列表设置为None。
- channel
需要停止播放的通道名。
- fadeout
若不为None,包含一个淡出效果时间,单位为秒。否则淡出时间取决于config.fade_music。
音效函数 link
大多数 renpy.music
函数在 renpy.sound
有别名(alias)。这些函数功能类似,主要差别在于它们默认作用于音效(sound)通道而不是音乐(music)通道,且默认不循环播放。