Ren’Py支持使用Python定义界面(screen),与使用Ren’Py界面语言能实现一样的效果。将一个界面函数传入函数 renpy.define_screen() ,就可以创建一个Python界面。创建的Python界面可以跟其他任何界面一样使用。
这个界面函数应该包含需求变量的对应参数,并忽略额外的关键词入参(也就是,函数的入参列表结尾是 **kwargs 。)。然后需要调用UI函数在界面上添加可视组件。界面函数需要能在任何互动行为开始后都能被调用。
为了确保函数重新运行时无缝的用户体验(并不导致某些东西重置),每次调用UI函数都提供 id 入参就很重要。如果重新创建了某个界面,Ren’Py会使用原可视组件内容的id更新每一个新的可视组件。id通过界面语言自动生成,但是手工处理界面时也许需要人工指定id。
Warning
不赞成也不推荐使用UI函数作为界面函数。
这是一个Python界面的样例:
init python:
def say_screen(who, what, **kwargs):
ui.window(id="window")
ui.vbox(id="say_vbox")
ui.text(who, id="who")
ui.text(what, id="what")
ui.close()
renpy.define_screen("say", say_screen)
下定函数支持定义、显示和隐藏界面。
renpy.call_screen(_screen_name, *args, **kwargs) link在程序上等效于call screen语句。
该函数将 _screen_name 做为一个界面显示,并触发某个互动行为。互动结束后界面隐藏,并返回互动结果。
不以下划线“_”开头的关键词入参都会传入界面的作用域。
如果关键词入参 _with_none 的值是False,互动结束后结尾的“with None”分句不会运行。
renpy.define_screen(name, function, modal="False", zorder="0", tag=None, variant=None) link定义一个名为 name 的界面。
调用该函数可以显示界面。调用该函数时,使用界面作用域(scope)作为需要的关键词入参。它会忽略其他的关键词入参。
这个函数需要调用ui函数将组件添加到界面上。
renpy.get_screen(name, layer=None) link返回在图层(layer)上名为 name 的界面可视组件。name 首先被看作是一个图像标签(tag)名,其次是一个界面名。如果那个界面不被显示,就返回None。
根据 name 可能得到一个界面名的列表,第一正在显示的界面作为最终结果返回。
该函数可以用于检查某个界面是否正在显示:
if renpy.get_screen("say"):
text "The say screen is showing."
else:
text "The say screen is hidden."
renpy.get_widget(screen, id, layer=None) link返回图层 layer 上的界面 screen 中带有 id 的组件(widget)。如果界面不存在或界面中不存在带有那个id的组件,则返回None。
renpy.get_widget_properties(id, screen=None, layer=None) link返回图层 layer 上界面 screen 中带有 id 的组件(widget)的特性(property)。如果 screen 为None,返回当前界面的特性(property)。该函数可以用在某个界面的Python或特性(property)代码中。
需要注意的是,这个函数返回结果是组件特性的字典。想要得到单个特性的值,就要进入字典取值。
renpy.hide_screen(tag, layer=None) link等效于“hide screen”语句。
隐藏图层 layer 上带图像标签 tag 的界面。
renpy.predicting() linkRen’Py正在预加载界面的情况下返回True。
renpy.show_screen(_screen_name, *_args, **kwargs) link等效于show screen语句。
这个函数使用下列关键词入参:
不以下划线(_)开头的关键词入参用于初始化界面的作用域。
renpy.start_predict_screen(_screen_name, *args, **kwargs) link触发Ren’Py开始缓存名为 _screen_name 的界面,那个界面之后会使用给定的入参显示。这个函数会替换之前 _screen_name 的缓存。需要停止缓存某个界面的话,调用 renpy.stop_predict_screen() 。
renpy.stop_predict_screen(name) link触发Ren’Py停止缓存名为 name 的界面。
renpy.variant(name) link如果 name 是Ren’Py中可用的某个界面变种(variant),就返回True。详见:ref:界面变种 <screen-variants>。这个函数可以用做条件表达式,在Python的if语句中根据界面变种选择使用对应的样式(style)。
name 也可以是一个界面变种列表,只要列表中任何变种被选择就返回True。
Note
Ren’Py的执行机制已经改变过,创建可视组件的UI函数现在可能比它们的等效界面语言效率要慢得多。
UI函数是界面语言语句的等效Python语句。每条界面语言语言都有一个同名的UI函数。例如,ui.text函数对应text语句,而ui.add函数对应add语句。
这里有一个界面语言的参数与Python入参之间的简单映射关系。界面语言参数变成固定位置入参,特性(property)变成关键词入参。举例,界面语言语句:
text "Hello, World" size 40 xalign 0.5
变成了:
ui.text("Hello, World", size=40, xalign=0.5)
(实际上要加一个 id 参数。)
根据使用的子组件数量分,总共有三组UI函数。
下列UI函数不使用任何子组件。
下列UI函数只使用一个子组件。子组件必须给定——如果不存在则使用ui.null()空对象。
下列UI函数使用多个子组件。它们持续使用这些子组件,直到调用 ui.close() 。
有几个UI函数没有对应的界面语言语句,因为他们对应界面语言中没有的概念。
ui.adjustment(range=1, value=0, step=None, page=None, changed=None, adjustable=None, ranged=None) linkadjustment对象表示可以通过某个条(bar)或视口(viewport)调整的值。Adjustment对象包括值的信息,值的范围,以及修改这个对象使用的最小步长和最大页面(page)。
下列参数分别对应Adjustment对象的字段(field)或者特性(property)。
调整的步长,一个数值。若为None,默认值是一个页面(page)的1/10大小,前提是设置了页面大小。否则默认为 range 大小的1/20。
使用鼠标滚轮滚动一个视口(viewport)时会用到这个值。
Adjustment对象的页面(page)大小。若为None,会通过视口(viewport)自动设置。如果没有设置,默认值是 range 大小的1/10。
当点击一个滚动条(scrollbar)时,这项值会被用到。
下列参数控制Adjustment对象的行为。
若为True,条(bar)可以修改Adjustment对象。若为False,则不能修改。
如果给定了 changed 函数或者Adjustment对象有一个关联的视口(viewport),那这项的默认值是True。否则默认值是False。
ui.change(value) link将Adjustment的值修改为 value ,并更新所有使用该Adjustment对象的条(bar)和视口(viewport)。
ui.at(transform) link指定创建的下一个可视组件使用的变换(transform)。这个做法已经淘汰,现在所有UI函数都会使用一个at入参。
ui.close() link关闭一个通过UI函数创建的可视组件。当可视组件关闭后,我们可以给它的父组件添加新的可视组件,如果没有可用的父组件则为其所在图层添加新的可视组件。
ui.detached() link不在任何图层或容器内添加下一个可视组件。如果你想要将某个UI函数的结果赋值给某个变量的话,就使用这个函数。
ui.interact(roll_forward=None, mouse='default') link触发某个与用户的交互动作,并返回交互的结果。这个函数让Ren’Py重绘界面并开始处理输入事件。当某个可视组件对应某个事件返回了一个值,那个值会从ui.interact返回,然后互动结束。
这个函数极少被直接调用。通常会被Ren’Py的其他部分调用,包括say语句、menu语句、with语句、pause语句、call screen语句、 renpy.input() 等等。不过,必要的时候也可以直接调用。
当某个互动结束,transient图层和所有“transient=True”的界面都会从场景(scene)列表中清除。
下列入参有文档说明。其他没有文档说明的入参属于Ren’Py内部使用。请都用关键词入参。
renpy.roll_forward_info() 函数的结果。ui.layer(name) link为名为 name 的图层添加可视组件。图层的关闭必须使用 ui.close() 。
ui.screen_id(id_, d) link如果使用了 id 和一个screen语句创建了界面组件(widget),则将可视组件 d 声明为界面组件 id 。
界面语言创建的许多可视组件都使用行为(action)作为入参。一个行为(action)是以下三种情况之一:
继承Action类对象的好处是,允许你重写类的方法(method),比如确认某个按钮什么情况下被选中的方法,以及判断按钮何时可用。
Action link要定义一个新的action,需要从这个类继承。 重写此类中的方法以更改action的行为。
__call__(self) link当行为激活状态下,这个方法会被调用。在很多情况下,行为会返回一个非None值,并让当前的互动结束。
继承后的类必须重写这个方法,使用默认方法会出现“未实现(NotImplemented)”错误(并被Ren’Py阻止直接报出这个错误)。
get_sensitive(self) link调用这个方法判断使用这个行为的按钮是否可用。如果按钮可用,则返回True。
注意,在这个方法返回False的情况下, __call__ 依然会被调用。
默认的实现会返回True。
get_selected(self) link如果按钮渲染为被选中的按钮就返回True,否则返回False。
默认的实现会返回False。
get_tooltip(self) link没有指定提示框(tooltip)的情况下,将为按钮获取一个默认的提示框。返回值是提示框的值,或者提示框未知的情况下返回None。
默认返回None。
periodic(self, st) link在每次互动的开头这个方法都会被调用一次,之后周期性调用。如果方法返回一个数值,就会在这个数值(单位为秒)的时间后再次调用,但其间也可以被很快直接调用。
这个方法的主要用途是调用
renpy.restart_interaction() ,前提是需要改变get_selected或get_sensitive的值。
方法使用一个入参:
unhovered(self):如果某个按钮(或类似对象)处于鼠标悬垂(hovered)状态下,当对象失去焦点时会调用这个方法。
想要在Python环境下运行某个行为(action),需要使用renpy.run。
renpy.is_selected(action) linkaction 表示selected时返回True,否则返回False。
renpy.is_sensitive(action) linkaction 表示sensitive时返回True,否则返回False。
renpy.run(action) link运行一个行为或者行为列表。单个行为调用时不带入参,行为列表按顺序执行,None则忽略。
行为列表中第一个行为执行结果作为函数的返回值。
ui.is_selected(action) linkaction 表示selected时返回True,否则返回False。
ui.is_sensitive(action) linkaction 表示sensitive时返回True,否则返回False。
当创建一个bar、vbar或hotbar时,可以使用一个BarValue对象作为条(bar)的值特性(property)。调用BarValue对象的方法可以调整数值和样式。
BarValue link定义一个新的BarValue时,可以继承这个类并重写一些方法。
get_adjustment(self) link调用这个方法可以获得一个针对条(bar)的adjustment对象。这个方法使用
ui.adjustment() 创建Adjustment对象,并返回创建的对象。
继承后的类必须重写这个方法,使用默认方法会出现“未实现(NotImplemented)”错误(并被Ren’Py阻止直接报出这个错误)。
get_style(self) link这个方法用于判断条(bar)使用的样式。返回的是一个二元的元组,元素类型为样式名称或Style对象。第一个元素用于bar,第二个元素用于vbar。
默认值是(“bar”, “vbar”)。
get_tooltip(self) link没有指定提示框(tooltip)的情况下,将为按钮获取一个默认的提示框。返回值是提示框的值,或者提示框未知的情况下返回None。
默认返回None。
replaces(self, other) link当某个界面更新,需要更换一个BarValue时,调用这个方法。它可以用于更新BarValue。调用顺序在get_adjustment之前。
注意, other 不需要与 self 的类型相同。
periodic(self, st) link在每次互动的开头这个方法都会被调用一次,之后周期性调用。如果方法返回一个数值,就会在这个数值(单位为秒)的时间后再次调用,但其间也可以被很快直接调用。调用顺序在get_adjustment之后。
它可以用于在某段时间内更新条(bar)的值,就像
AnimatedValue() 一样。为了实现这点,get_adjustment应该存储Adjustment对象,并周期性调用Adjustment的修改方法。
当创建一项输入时,一个InputValue对象可以用作输入的 value 特性(property)。调用InputValue对象的方法可以实现:获取和设置文本,判断输入是否可编辑,以及回车键按下后的处理。
InputValue link继承这个类,并定义一个新的InputValue,需要重写部分或全部方法,并设置默认字段(field)的值。
default link若为True,默认输入是可以编辑的。(当其在界面上显示时,可能会带有插入记号。)
get_text(self) link返回输入的默认文本。这个方法必须实现。
set_text(self, s) link当输入文本改变时,调用这个方法修改为新的文本。这个方法必须实现。
enter(self) link当用户按下回车键时调用。如果其返回一个非None值,那个值会返回给交互行为。其也可以使用renpy.IgnoreEvent()忽略回车键的按下。否则,回车键按下的消息会广播给其他可视组件。
下列行为也是InputValue对象的可用方法:
Enable() link返回一个行为,启用输入的文本编辑。
Disable() link返回一个行为,禁用输入的文本编辑。
Toggle() link返回一个行为,切换文本的可编辑状态。
Ren’Py支持定义定制化界面语言语句。创作者定义的界面语言语句本质上是变相使用了界面语言中的 use语句 。固定位置入参不变,特性(property)变成了关键词参数。如果自定义的语句后面有一个语句块(block),use语句也支持。例如,下面的定制化界面语言语句:
titledwindow "Test Window":
icon "icon.png"
text "This is a test."
可以变成:
use titledwindow("Test Window", icon="icon.png"):
text "This is a test."
创作者定义的界面语言语句必须在python early语句块(block)中注册。还有,包含创作者定义的界面语言语句的文件必须在使用这个语句的文件之前加载。由于Ren’Py按照unicode顺序加载文件,通常合理的做法是,在注册创作者自定义语句的文件加上前缀“01”之类一个不大的数字。
创作者定义的界面语言语句使用renpy.register_sl_statement函数进行注册:
renpy.register_sl_displayable(name, displayable, style, nchildren=0, scope=False, replaces=False, default_keywords={}) link注册一个界面语言语句,用于创建一个可视组件。
这是一个函数,被调用后返回一个可视组件对象。所有固定位置入参、特性(property)和样式特性都可以作为入参传入这个函数。其他关键词入参请看后面部分。
这个函数的返回值必须是一个可视组件。如果它返回了多个可视组件,最外层可视组件的“_main”属性(attribute)应该被设置成那个“主”可视组件——子组件添加在“主”组件上。
style 关键词传入可视组件的处理函数。可视组件的子组件数量。可能是:
下列入参应该使用作为关键词入参传入:
返回一个对象,并可以通过调用下列方法为这个对象添加固定位置入参和特性(property)。每个方法都会返回调用方法的对象自身,并允许方法链接起来用。
add_positional(name) link添加一个名为 name 的固定位置入参。
add_property(name) link添加一个名为 name 的特性(property)。特性会作为关键词入参传入。
add_style_property(name) link添加一个特性的族(family),以 name 结尾,沿用样式特性的前缀。例如,调用时使用(“size”),这个方法就定了size、idle_size、hover_size等。
add_prefix_style_property(prefix, name) link添加一个特性的族(family),名字由 prefix (样式特性前缀)和 name 构成。例如,调用时使用了前缀 text_ 和名称 size ,这个方法就创建了text_size、text_idle_size、text_hover_size等。
renpy.register_sl_statement(name, positional=0, children='many', screen=None) link使用Ren’Py注册一个定制化界面语言语句。
返回的对象可以被添加固定位置入参和特性(property)。这个对象有一个与 renpy.register_sl_displayable() 返回对象相同的“.add_”方法。
做一个创作者定义界面语言语句的例子,这里是 titledwindow 语句的实现。首先,在早期加载的文件——像名为“01custom.rpy”就加载足够早——中 python early 语句块中注册定制化语句。注册的脚本如下:
python early:
renpy.register_sl_statement("titledwindow", children=1).add_positional("title").add_property("icon").add_property("pos")
然后,我们定义一个实现了定制化语句的界面。这个界面可以在任何文件中定义。比如:
screen titledwindow(title, icon=None, pos=(0, 0)):
drag:
pos pos
frame:
background "#00000080"
has vbox
hbox:
if icon is not None:
add icon
text title
null height 15
transclude
需要大量传递特性(property)值时,更合理的方法是使用 **properties 参数,例如:
screen titledwindow(title, icon=None, **properties):
frame:
# 如果properties参数中不包含background,则会使用默认值。
background "#00000080"
properties properties
has vbox
hbox:
if icon is not None:
add icon
text title
null height 15
transclude