10526 字
53 分钟
--
界面和界面语言

想要实现自己的界面,接需要使用screen,这是没法避开的。

界面和界面语言#

用户在Ren’Py游戏中所有的可见元素可以分为图像和用户接口两大类。图像通过scene、show和hide语句向用户展示,也是故事叙述的大头。其他所有可见的元素都属于用户接口。用户接口可以通过界面实现定制化。

界面有下列4种方式显示:

  • 隐含在脚本语句执行中。例如,say语句会触发 say 界面的显示。
  • 自动显示。例如,Ren’Py启动后或者用户退回到主菜单时,会显示 main_menu 界面。
  • 作为一个用户行为,与按钮、鼠标按键或者键盘按键相关联。默认情况下, save 界面是用户鼠标右击或者按下退出(Esc)键才会展示。也可以定义一个on-screen按钮用于显示 save 界面。
  • 明确使用某些语句触发界面显示的情况。

注意!可以同时显示多个界面,但是会存在遮挡问题

每次交互行为的启动或重启,都会更新界面。注意 with None 语句不会触发互动,也不会更新界面。

界面语言#

界面语言是显示界面最正式的办法。它包含定义新界面的语句、添加可视组件至界面的语句和控制型语句。

这是一个界面的样例:

screen say(who, what):
window id "window":
vbox:
spacing 10
text who id "who"
text what id "what"

界面语言的语法#

大多数界面语言语句使用通用的语法。(某些控制语句使用其他语法。)语句的开头以某个关键词进入。

如果语句使用参数,参数就跟着开头的关键词后面。参数列表是使用空格分隔的简单表达式,除非有特殊情况。

固定位置参数后面会跟一个特性(property)列表。一个特性包括特性名称和特性值组成。特性值是简单表达式,除非有特殊情况。特性列表中各个特性使用空格分隔。

如果某个语句以英文冒号(:)结尾,后面就会跟一个语句块(block)。语句块的每一行可能是以下两者之一:

  • 一个特性列表。
  • 一条界面语言语句。

screen#

screen 语句在Ren’Py脚本语言中用于定义一个新的界面。其使用界面语言通用语法。

screen语句使用一个参数,即界面名。界面名不是一个简单表达式,可以使用以下特性:

  • modal

    若为True,该界面是一个模态框(modal)。一个模态框界面防止用于与它下层的可视组件发生互动,除了默认的keymap类。

  • sensitive

    决定界面是否被启用的表达式。每次交互行为时,该表达式都至少会被计算一次。

  • tag

    被当作一个变量名处理,而不是一个表达式。该特性指定一个与界面关联的图像标签(tag)。显示某个界面会替换带用相同图像标签的其他界面。这可以用来确保在相同的上下文环境下,同一时间只有显示一个菜单界面。

  • zorder

    该特性用于控制向用户显示界面的远近。数值越大,界面距离用户越近。默认值是0。

  • variant

    如果该特性出现,应该是一个字符串或者字符串的列表,给定了待定义的变种界面

  • style_prefix

    该特性是一个字符串,用于向界面所有子组件的样式提供一个前缀,

  • layer

    该特性是一个字符串,给定了显示界面的默认图层(layer)名。

  • roll_forward

    若为True,使用 call screen 语句时将启用前向滚动。 若为False,禁用前向滚动。 若为None或没有指定,则使用 config.call_screen_roll_forward 的值。使用 call screen 语句启用前向滚动后,将保留返回值和待跳转标签,但不会引发副作用。 这意味着,如果界面中只包含 Jump()Return() 行为,启用 roll-forward 是安全的。 其他行为则在前向更难懂时可能会引发副作用。

如果界面定义中的第一行是一个Python字符串,通常是界面的描述信息。 该描述信息可以使用 renpy.get_screen_docstring() 检索。

screen hello_world():
"""
显示hello world信息。
"""
tag example
zorder 1
modal False
text "Hello, World."

界面可以使用一个参数列表:

screen center_text(s, size=42):
text s size size

如果界面不带任何参数,依然需要给一对空的圆括号。

用户接口语句#

用户接口语句用于创建可视组件并添加至界面或某个封闭的可视组件。它们允许向用户显示信息,用户与游戏的互动,以及游戏中各种事件消息的相互作用。

所有用户接口语句使用下列通用特性:

  • atlink

    一个transform、transform的列表或者匿名transform(未定义直接在at中使用的transform)。transform hello_t: align (0.7, 0.5) alpha 0.0 linear 0.5 alpha 1.0 screen hello_title(): text "Hello." at hello_t text "Hello.": at transform: align (0.2, 0.5) alpha 0.0 linear 0.5 alpha 1.0 可用于wrap可视组件。show、hide、replace和replaced external事件消息会传入transform,前提是transform是被直接添加到界面上的。例如,如果某个vbox在某transform中被wrap,并直接添加到界面上,事件消息就会传给那个transform。但如果某个按键文本是添加到vbox再被加入transform中被warp,那么第二层的transform就不会接收到事件消息。

  • default_focuslink

    如果出现了该特性,并且值为True,默认情况下该可视组件会得到焦点。只有一个可视组件可以拥有该特性。只有当最后一次互动不是鼠标点击、鼠标移动或触控点击时,才会使用默认焦点。

  • extra_altlink

    该特性是在 自动语音 中提到的额外语音。 启用自动语音后,当玩家按下键盘问号“?”键时,将播放设置的额外语音。可视组件的所有子组件都会继承该 extra_alt 特性。 除非子组件设置了自己的 extra_alt 特性。额外文本的设计,为视力不佳的玩家提供各种可视组件的更多信息。

  • focuslink

    该特性使用一个字符串或整数,并出于获取焦点的需求,给出一个可视组件的名称。 Ren’Py会搜索与focus结构相似的特性名,并决定在某交互行为开始后最先获取到focus的可视组件。 如果某个框(box)给定了一个focus名,并且框内的第三个按钮在交互行为结束时获取到焦点,某个同名框(box)的第三个按钮会在下一个交互行为开头显示为高亮。

  • group_altlink

    该特性是在 自动语音 中提到的额外语音组前缀。 启动自动语音后,带有该特性匹配前缀的可视组件首次获得焦点时,将播放设置的文本转语音。 但相同前缀的组件获得焦点后不会重复播放,直到不同前缀的组件获得焦点。可视组件的所有子组件都会继承该 group_alt 特性。 除非子组件设置了自己的 group_alt 特性。

  • idlink

    用户接口语句的标识号。当某个界面显示时,特性值可以通过给定的标识符提供给可视组件。某些界面会根据创建的标识号请求某个可视组件。使用某个id创建可视组件后,该id就会存储为可视组件对象的id属性,类型为字符串。

  • prefer_screen_to_idlink

    若为True,当遇到界面和可视组件提供了相同特性的值时,选用界面的特性。 若为默认值False,则选用可视组件的特性。 (该项可以用于,角色对象设置覆盖界面特性的需求。)

  • stylelink

    应用于可视组件的样式名。其可能是一个字符串名,也可能是一个样式对象。该样式指定样式特性的默认值。

  • style_prefixlink

    向可视组件及其子组件的样式提供了一个前缀,例外情况是某些子组件用一个指定的样式或样式前缀。样式名由样式前缀、下划线和样式后缀组成。样式后缀通过样式后缀 style_suffix 或可视组件决定。例如,如果某个vbox有一个样式前缀 "pref" ,这个vbox的样式名就是 "pref_vbox" 。除非设置了某个指定的样式或者样式前缀,vbox内的按钮会用样式 "pref_button"。如果样式不存在的话,使用这种方式接入的样式会被自动创建。将前缀设置为 None 会将可视组件及其子组件的所有前缀都移除。

  • style_grouplink

    style_prefix 的一个别名,用在旧版本的Ren’Py中。

  • style_suffixlink

    指定后缀,与 style_prefix 连在一起创建一个样式名。如果后缀是 "small_button" ,前缀是 "pref" ,实用的样式名就是 "pref_small_button" 。如果不使用样式前缀,就是直接使用样式名。样式后缀就会只应用于某一个可视组件,而不会用于其子组件。

  • tooltiplink

    声明某个可视组件的工具提示框。当可视组件获得焦点时,该特性值会启用 GetTooltip() 函数。详见 Tooltips 章节。 传入工具提示框的对象必须支持相等性(equality)。如果不支持比较相等,可能会导致无限死循环。

  • argumentslink

    一个元组或列表,包含传入可视组件的额外固定位置入参。

  • propertieslink

    一个字典,包含传入可视组件的额外特性。

许多用户接口语句使用样式特性类或者transform特性。这些特性可以使用相关联的样式前缀,前缀决定了特性被应用的时机。例如,如果带有 hover_size 特性,就会设置文本在鼠标悬停状态时的文本字号。

UI语句可以使用 as 从句,后面带一个变量名,不需要引号。 语句创建的可视组件对象将声明为变量。(在这里可以找到一个样例 拖拽组件 。)

创建一个原本水平的条(bar),可用于查看和调整数据。其使用以下特性:

  • valuelink

    条(bar)的当前值。可以是一个 条(bar)值 对象,或者一个数值。

  • rangelink

    条(bar)的最大值。如果 value 是一个数值的话,这个特性是必须的。如果 value 是一个条=值对象的话,该特性会被忽略。

  • adjustmentlink

    该条(bar)所调整的 ui.adjustment() 对象。

  • changedlink

    若该值存在,应该是一个Python函数。当 adjustment 改变时,这个函数会用调整后的值被调用。

  • hoveredlink

    当条(bar)获取焦点后的行为。

  • unhoveredlink

    当条(bar)失去焦点后的行为。

  • releasedlink

    在条(bar)被释放时执行指定的行为。甚至条的数值没有发生变化时依然会被调用执行。

  • actionlink

    当条(bar)值改变时执行的行为。

  • thumb_alignlink

    滑块的对齐方式,表示与bar的相对位置。 如果bar与滑块的尺寸不同——例如,滑块比水平bar还要高——thumb_align可以设置为0.5,让滑块与bar居中对齐。

value 或者 adjustment 之一必须给定。除此之外,该函数还是用以下特性:

条(bar)不包含任何子组件。

screen volume_controls():
frame:
has vbox
bar value Preference("sound volume") released Play("sound", "audio/sample_sound.ogg")
bar value Preference("music volume")
bar value Preference("voice volume")

创建界面的一块区域,可以通过点击激活并运行一个行为。按钮(button)不接受参数,可以拥有下列特性。

  • actionlink

    当按键激活时会执行的行为。按钮被点击时会被激活,用户也可以使用其他方法选中按钮并按下键盘“Enter”键。在 sensitive 特性没有提供的情况下,它还能控制让按钮改为sensitive(启用)状态;同样,在 selected 特性没有提供的情况下,它也能控制按钮被选中。

  • alternatelink

    使用转化过的办法在按钮激活后运行的行为。当用户在基于鼠标的平台上那个点击鼠标右键,或者用户在基于触控的平台上长按某个按钮,都会触发。

  • hoveredlink

    当按钮获取焦点时运行的行为。

  • unhoveredlink

    当按钮失去焦点时运行的行为。

  • selectedlink

    决定按钮是否被选择的表达式。每次交互行为时,该表达式都至少会被计算一次。如果该特性没有提供,用户行为会最终决定按钮是否被选择。

  • sensitivelink

    决定按钮是否被启用的表达式。每次交互行为时,该表达式都至少会被计算一次。如果该特性没有提供,用户行为会最终决定按钮是否被启用。

  • keysymlink

    给定了一个 keysym 的字符串。字符串描述了键盘对应的按键,当那个按键被按下后,会调用按钮的行为。

  • alternate_keysymlink

    给定了一个 keysym 的字符串。字符串描述了键盘对应的按键,当那个按键被按下后,会调用按钮的可选变换行为。

它还可以拥有下列特性:

按钮拥有一个子组件。如果0个、两个或者更多子组件被应用,他们全部会自动整合为一个固定布局(fixed),并添加到按钮上。

dismiss 语句创建一个高度特化的dismiss可视组件,在其他可视组件都没有获得焦点时,dismiss组件就会获得焦点,并在激活后执行一个行为。 从效果上来说类似say语句。

dismiss组件的应用场景不多,大多数时候与某个模态frame搭配,当用户点击frame之外的区域时激活dismiss。此外,偶尔也能用作弹窗。

该组件可拥有下列特性:

  • actionlink

    当dismiss组件激活时执行的行为。该特性必须指定。

  • keysymlink

    指定一个字符串,代替默认的 keysym 字典中dismiss键对应的值。

  • modallink

    默认情况下,dismiss组件是模态的,不允许向其“背后”的其他可视组件传递事件消息。

该组件还可拥有下列特性:

这是一个dismiss的使用样例:

screen dismiss_test():
dismiss action Return()
frame:
modal True
align (.5, .3)
padding (20, 20)
has vbox
text "这是一条非常重要的信息。":
xalign 0.5
text_align 0.5
# Dismiss can be confusing on its own, so we'll add a button as well.
# 译者注:上面一句注释似乎是作者在玩梗,但是太冷导致不知道如何翻译。
textbutton "Dismiss":
xalign 0.5
action Return()

dismiss组件还可以与 nearrect 协同实现其他效果。

fixed创建了一块用于添加子组件的区域。默认情况下,固定布局(fixed)会扩展并填充整个可用区域,但 xmaximumymaximum 特性可以改变这点。

子组件们使用自身的位置样式特性实现布局。如果没有合适的设置位置,它们可能会重叠。

fixed语句不接受参数,后面跟以下特性:

fix使用多个子组件,它们会被添加到固定布局中。

显示创建一个固定布局可视组件通常并不是必要的。每个界面都被包含在一个固定布局可视组件中,并且很多界面语言语句会自动创建一个固定布局的可视组件,前提是他们有两个或更多子组件。

screen ask_are_you_sure:
fixed:
text "Are you sure?" xalign 0.5 yalign 0.3
textbutton "Yes" xalign 0.33 yalign 0.5 action Return(True)
textbutton "No" xalign 0.66 yalign 0.5 action Return(False)

框架(frame)是一个窗口。该窗口包含一个背景,可用于显示用户接口元素,例如按钮、条(bar)和文本。其拥有下列特性:

frame拥有一个子组件。如果0个、两个或者更多子组件被应用,他们全部会自动整合为一个固定布局(fixed),并添加到按钮上。

screen test_frame():
frame:
xpadding 10
ypadding 10
xalign 0.5
yalign 0.5
vbox:
text "Display"
null height 10
textbutton "Fullscreen" action Preference("display", "fullscreen")
textbutton "Window" action Preference("display", "window")

grid在一个网格系统中显示其子组件。每个子组件都会分配相同的区域大小,这个区域大小可以容纳最大的子组件。

grid使用两个参数。第一个参数是网格的行号,第二个参数是网格的列号。其拥有下列特性:

  • transposelink

    若值为False,网格转置。

  • right_to_leftlink

    若为True,按从右往左的顺序填充网格单元。默认则是按从左往右的顺序填充网格单元。

  • bottom_to_toplink

    若为True,按从下往上的顺序填充网格单元。默认则是按从上往下的顺序填充网格单元。

其还使用以下特性:

grid中必须给定“行数×列数”的子组件。如果给出其他数量的子组件会发生错误。

screen grid_test:
grid 2 3:
text "Top-Left"
text "Top-Right"
text "Center-Left"
text "Center-Right"
text "Bottom-Left"
text "Bottom-Right"

hbox的各个子组件会边靠着边显示,都在一个不可见的水平方块(box)内。其不接受参数,后面跟以下特性:

UI可视组件的子组件会被添加到方框(box)中。

screen hbox_text():
hbox:
text "Left"
text "Right"

创建一个包含图像的按钮,当指针悬停在按钮上时,图像状态会发生改变。其不接受参数,拥有下列特性:

  • autolink

    按钮使用图片自动定义。这个特性是个包含 %s 的字符串。如果某个图片特性是省略的,%s会被替换为对应特性名称,并使用对应值作为对应特性的默认值。例如,如果 auto 是 “button_%s.png”,并且 idle 特性省略,那么idle的默认值就是 “button_idle.png”。类似的,如果 auto 是”button %s”,那么 button idle 图像就会被应用。auto 特性的具体行为可以修改 config.imagemap_auto_function 实现定制化。

  • insensitivelink

    当按钮不可用状态时,使用在按钮上的图像。

  • idlelink

    当按钮没有得到焦点状态时,使用在按钮上的图像。

  • hoverlink

    当按钮得到焦点状态时,使用在按钮上的图像。

  • selected_idlelink

    当按钮被选中但是没有得到焦点状态时,使用在按钮上的图像。

  • selected_hoverlink

    当按钮被选中而且得到焦点状态时,使用在按钮上的图像。

  • actionlink

    当按钮被激活时运行的行为。当 sensitive 和 selected 特性没有提供的情况下, action 特性也控制那两种特性表现。

  • alternatelink

    使用转化过的办法在按钮激活后运行的行为。当用户在基于鼠标的平台上那个点击鼠标右键,或者用户在基于触控的平台上长按某个按钮,都会触发。

  • hoveredlink

    当按钮获取焦点时运行的行为。

  • unhoveredlink

    当按钮失去焦点时运行的行为。

  • selectedlink

    决定按钮是否被选择的表达式。每次交互行为时,该表达式都至少会被计算一次。如果该特性没有提供,用户行为会最终决定按钮是否被选择。

  • sensitivelink

    决定按钮是否被启用的表达式。每次交互行为时,该表达式都至少会被计算一次。如果该特性没有提供,用户行为会最终决定按钮是否被启用。

  • keysymlink

    给定了一个 keysym 的字符串。字符串描述了键盘对应的按键,当那个按键被按下后,会调用按钮的行为。

  • alternate_keysymlink

    给定了一个 keysym 的字符串。字符串描述了键盘对应的按键,当那个按键被按下后,会调用按钮的变换行为。

它还可以拥有下列特性:

图片按钮没有子组件。

screen gui_game_menu():
vbox xalign 1.0 yalign 1.0:
imagebutton auto "save_%s.png" action ShowMenu('save')
imagebutton auto "prefs_%s.png" action ShowMenu('preferences')
imagebutton auto "skip_%s.png" action Skip()
imagebutton auto "afm_%s.png" action Preference("auto-forward mode", "toggle")

创建一个文本输入区域,允许用户输入文本。当用户按下回车键,输入的文本会通过交互行为返回。(如果界面是通过 call screen 唤起的,输入结果会存放在 _return 变量中。)

受限于支持的库,在安卓和Web平替上,输入框只支持英文字母。

input语句不接受参数,可以跟下列特性:

  • valuelink

    此次输入使用的 input value 对象。输入值对象决定了以下情况的默认处理方式:默认值从哪里获取,文本改变时会发生什么,用户输入回车后会发生什么,以及文本是否可编辑。value 应跟 default 和 changed 在相同的时间点给定。

  • defaultlink

    在输入框中的默认文本。

  • lengthlink

    输入框中允许的最大文本长度。

  • pixel_widthlink

    输入框最大像素宽度。如果输入一个字符会导致输入超出这个宽度,按键(keypress)事件消息就会被忽略。

  • allowlink

    包含所有允许输入字符的字符串。(默认情况下允许输入任何字符。)

  • excludelink

    包含不允许输入字符的字符串。(默认情况下为空“{}”。)

  • copypastelink

    若为True,可以在这个输入栏中启用复制粘贴功能。(默认禁用。)

  • prefixlink

    一个不可变的字符串,自动添加在用户输入前面。

  • suffixlink

    一个不可变的字符串,自动添加在用户输入后面。

  • changedlink

    当用于输入字符串改变时,使用输入字符串调用的一个Python函数。

  • masklink

    该值是一个字符串,可将文本中的字符都替换显示为指定字符串。可用于表现一个密码。

  • caret_blinklink

    若非False,指定光标闪烁间隔时间。此项将覆盖 config.input_caret_blink 配置项。

  • multilinelink

    若为True,可以使用键盘将光标移动到下一行(默认键盘输入为Shift+Enter换行,可以修改config.keymap[‘input_next_line’]来改为其他按键方式)。

  • actionlink

    若不是None,该项是一个动作(action),在按下回车(Enter)并激活输入结果时运行。 默认的输入后行为会直接返回输入值,该项可以覆盖默认行为。该项主要用于对输入结果 value 做预处理的需求场景。

  • arrowkeyslink

    若为True(默认值),键盘的方向键可以让输入框中的光标左右移动。 若为False,键盘的方向键不能移动输入光标,而实现其他功能,比如在不同组件间切换焦点。

输入框还拥有下列特性:

输入框不包含子组件。

screen input_screen():
window:
has vbox
text "Enter your name."
input default "Joseph P. Blow, ESQ."

key语句创建一个键盘按键绑定,可以通过按键运行某个行为。key语句的应用场景比较宽泛,可以支持手柄和鼠标事件。

key语句有一个固定位置参数,一个需要绑定的按键名字符串。详见 定制按键映射 。key语句使用两个特性:

  • actionlink

    这个特性给定了按键(keypress)事件发生后触发的行为。该特性必须存在。

  • capturelink

    若为True,即默认值,捕获事件并不会由其他可视组件处理。 若为False,则按键行为不会结束此次交互,其他可视组件会处理事件。

key不包含子组件。

screen keymap_screen():
key "game_menu" action ShowMenu('save')
key "p" action ShowMenu('preferences')
key ["s", "w"] action Screenshot()

使用脚本标签(label)样式创建一个窗口(window),并且将文本内容放置在窗口内。这种联合体用于在某个框架(frame)中将某些元素标签化。

label语句包含一个固定位置参数,即标签的文本。其拥有下列特性:

  • text_stylelink

    用于按钮文本的样式名。如果未提供并且样式特性是一个字符串的话, "_text" 会自动添加到字符串后面作为默认的文本样式。

  • text_-link

    其他有 text 前缀的特性会把前缀去掉,然后传给文本组件(text displayable)。

label语句还可以使用以下特性:

label语句不包含任何子组件。

screen display_preference():
frame:
has vbox
label "Display"
textbutton "Fullscreen" action Preference("display", "fullscreen")
textbutton "Window" action Preference("display", "window")

mousearea是界面上划出一块区域,用于检测鼠标的进入或离开。与按钮(button)不同的是,鼠标区域不能获得焦点,所以在按钮内部可以存在一块鼠标区域。mousearea语句不接受参数,可以拥有下列特性:

  • hoveredlink

    当鼠标进入鼠标区域时运行的行为。

  • unhoveredlink

    当鼠标离开鼠标区域时运行的行为。

  • focus_masklink

    focus_mask 样式特性,可以是某个可视组件或者None。如果是一个可视组件,鼠标区域值应只放在可视组件不透明的部分上面。(那个可视组件不会展示给用户。)

mousearea语句拥有下列特性:

mousearea语句不含子组件。

通常来说,mousearea语句会给定区域样式特性,控制鼠标区域的大小和坐标。如果不控制鼠标区域大小,就会自动占用整个界面,那种行为的用处比较小。

Note

由于Ren’Py游戏可以使用键盘和手柄,所以复用鼠标区域功能就往往有其他的意义。

screen button_overlay():
mousearea:
area (0, 0, 1.0, 100)
hovered Show("buttons", transition=dissolve)
unhovered Hide("buttons", transition=dissolve)
screen buttons():
hbox:
textbutton "Save" action ShowMenu("save")
textbutton "Prefs" action ShowMenu("preferences")
textbutton "Skip" action Skip()
textbutton "Auto" action Preference("auto-forward", "toggle")
label start:
show screen button_overlay

nearrect 语句后面带一个子组件名,并把对应的子组件放在附近的一个矩形区域中。 通常使用 CaptureFocus() 行为函数获取焦点附近的矩形区域。 nearrect可以用于提示信息和下落、下拉菜单。

nearrect组件拥有下列特性:

  • rectlink

    若给定,参数应该是一个(x, y, w, h)形式的矩形,将子组件的位置信息与矩形关联。具体关联方式见下面的描述。

  • focuslink

    若给定,该参数应该是一个字符串。字符串传递给 GetFocusRect() 函数并寻找合适的矩形区域。 若找到了合适的矩形,则渲染对应子组件。将参数设置为“tooltip”时,将会在最后获得焦点的可视组件位置显示提示信息。该特性会覆盖 rect。

  • preferred_sidelink

    取值可以是 "left""top""right""bottom" 其中一个,表示优先贴近哪条边。 如果某条边空间不足,则选择对边。默认值为”botton”。

  • prefer_toplink

    已弃用,等效于 preferred_side "top"

  • invert_offsetslink

    若为True,如果 preferred_side 没有足够空间时,会将xoffset和yoffset乘以-1。 这样子组件改为贴近对边时的偏移量才可能合适。默认值为False。

该组件还可拥有下列特性:

Nearrect differs from the other layouts in that it positions its child near the given rectangle, rather than inside it. For a preferred_side of "top" or "bottom" (resp. "left", "right"), the child is first rendered with the full width (resp. height) available, and the maximum of the height (resp. width) above and below the rectangle. The y position (resp. x position) is then computed as followed. nearrect与其他组件布局的位置计算方式不同,不把其子组件放在指定矩形区域内,而是放在指定矩形区域附近。 若其 preferred_side 特性的值为 "top""bottom",子组件首先以完整的宽度渲染, 然后计算矩形区域上方和下方分别可能的最大可用高度。最后根据下面的原则计算结果确定y轴方向的位置。

  • 如果子组件能够匹配矩形区域的 preferred_side 要求,直接将子组件放在与矩形区域相邻的对应位置。
  • 否则,将子组件放在与矩形 preferred_side 的对边。
  • 否则,将子组件放在与矩形 preferred_side 指定相邻的对应位置。

x轴方向的位置使用通用准则计算,可以设置子组件的 xposxanchorxalign 特性。 位置特性的值与矩形区域的x坐标相关。如果是浮点值,则与矩形区域的宽度相关。

xoffsetyoffset 特性的应用方式与其他组件相同。

如果nearrect组件的子组件是一个变换(transform),变换指定了 showhide 事件响应。 但是,实际位置会发生改变。 nearrect最好放置在界面顶层,变换和位置特性应用到其子组件上,而不是nearrect自身。

这是一个下拉菜单的样例:

default difficulty = "简单"
screen select_difficulty():
# 根据实际需要,此处的frame可以拥有非常复杂的布局。
frame:
align (.5, .3)
padding (20, 20)
has vbox
# 点击此按钮激活下拉菜单
textbutton "选择难度: [difficulty]":
# 该行为捕获获取焦点的矩形区域,并显示下拉菜单
action CaptureFocus("diff_drop")
textbutton "完成":
action Return()
# 其他界面元素可以写在这里,但nearrect相关的元素需要写在最上层。
# nearrect的子组件最后显示,只能要分开写。
# 仅当焦点区域捕获成功,才显示下拉菜单。
# 可以使用showif替代基本的if语句。
if GetFocusRect("diff_drop"):
# 如果玩家点击了frame之外的区域,使用dismiss关闭下拉菜单。
# 此处使用ClearFocus行为函数关闭。
dismiss action ClearFocus("diff_drop")
# nearrect组件的位置放在之前定义的按钮附近(通常是下方)。
nearrect:
focus "diff_drop"
# Finally, this frame contains the choices in the dropdown, with
# each using ClearFocus to dismiss the dropdown.
# 最后,下拉菜单里的各个选项放在一个frame中。
# 每个选项行为都使用ClearFocus,以隐藏下拉菜单。
frame:
modal True
has vbox
textbutton "简单" action [ SetVariable("difficulty", "简单"), ClearFocus("diff_drop") ]
textbutton "正常" action [ SetVariable("difficulty", "正常"), ClearFocus("diff_drop") ]
textbutton "困难" action [ SetVariable("difficulty", "困难"), ClearFocus("diff_drop") ]
textbutton "噩梦" action [ SetVariable("difficulty", "噩梦"), ClearFocus("diff_drop") ]

下拉菜单可以通过样式提升观感,此处不做具体演示了。

null语句在界面中插入了一块空的区域。其可以用于物体分隔开。null语句不包含参数,可以拥有下列特性:

  • widthlink

    空区域的宽度,单位是像素。

  • heightlink

    空区域的高度,单位是像素。

null语句可以使用以下样式:

null语句不包含子组件:

screen text_box():
vbox:
text "这是标题。"
null height 20
text "这是正文。"

side语句把可视组件放置在一个网格的角落或者中间。其使用一个字符串型参数,字符串内包含空格样式的位置信息列表,用于配置子组件。列表中的每个元素都应该是下列字符串之一:

‘c’, ‘t’, ‘b’, ‘l’, ‘r’, ‘tl’, ‘tr’, ‘bl’, ‘br’

‘c’表示中间,’t’表示上部,’tl’表示左上,’br’表示右下,以此类推。

side语句使用下列的特性:

  • spacinglink

    网格中各行和各列之间的间隔。

side语句还可以使用如下特性:

当渲染时,先渲染四角,然后是四边,最后是中间。四角和四边在渲染阶段的初始可用区域是0,所以有必要提供一个最小尺寸(使用 xminimumyminimum),以确保渲染成功。

添加子组件的顺序(或者使用入参的子字符串顺序)控制显示顺序,最后添加的显示在最上层。 可以通过配置项 config.keep_side_render_order 禁用。

使用各子组件时分别占据网格单元列表中的一个位置,所以网格单元应与子组件数量相同。

screen side_test():
side "c tl br":
text "Center"
text "Top-Left"
text "Bottom-Right"

text语句会显示文本。其使用一个参数,就是用于显示的文本内容。其也拥有下列特性:

text语句没有子组件。

screen hello_world():
text "Hello, World." size 40

创建一个包含脚本标签(label)的按钮。按钮使用一个参数,即按钮内显示的文本内容。其可以拥有下列特性:

  • actionlink

    当按钮被激活时运行的行为。当 sensitive 和 selected 特性没有提供的情况下, action 特性也控制那两种特性表现。

  • alternatelink

    使用转化过的办法在按钮激活后运行的行为。当用户在基于鼠标的平台上那个点击鼠标右键,或者用户在基于触控的平台上长按某个按钮,都会触发。

  • hoveredlink

    当按钮获取焦点时运行的行为。

  • unhoveredlink

    当按钮失去焦点时运行的行为。

  • selectedlink

    决定按钮是否被选择的表达式。每次交互行为时,该表达式都至少会被计算一次。如果该特性没有提供,用户行为会最终决定按钮是否被选择。

  • sensitivelink

    决定按钮是否被启用的表达式。每次交互行为时,该表达式都至少会被计算一次。如果该特性没有提供,用户行为会最终决定按钮是否被启用。

  • keysymlink

    给定了一个 keysym 的字符串。字符串描述了键盘对应的按键,当那个按键被按下后,会调用按钮的行为。

  • alternate_keysymlink

    给定了一个 keysym 的字符串。字符串描述了键盘对应的按键,当那个按键被按下后,会调用按钮的变换行为。

  • text_stylelink

    用于按钮文本的样式名。如果未提供并且样式特性是一个字符串的话, "_text" 会自动添加到字符串后面作为默认的文本样式。

  • text_-link

    其他有 text 前缀的特性会把前缀去掉,然后传给文本组件(text displayable)。

textbutton还可以使用如下特性:

其不包含子组件。

screen textbutton_screen():
vbox:
textbutton "Wine" action Jump("wine")
textbutton "Women" action Jump("women")
textbutton "Song" action Jump("song")

timer语句会创建一个计时器,当预订的时间结束后运行某个行为。其使用一个固定位置参数,给出计时的时间值,单位为秒。timer语句拥有下列特性:

  • actionlink

    计时结束后会运行的行为。这项特性是必须存在的。

  • repeatlink

    若为True,计时结束后重置时间并重新开始计时。

  • modallink

    若为True,模态界面不会触发计时器。若为False或没有指定值,模态界面显示状态下依然进行计时。

timer不包含子组件。

screen timer_test():
vbox:
textbutton "Yes." action Jump("yes")
textbutton "No." action Jump("no")
timer 3.0 action Jump("too_slow")

将一个transform应用于其子组件。transform没有参数,可以拥有下列特性:

transform下有一个子组件。

等效于原生垂直的 bar 。 使用特性与条 bar 一样。

screen volume_controls():
frame:
has hbox
vbar value Preference("sound volume")
vbar value Preference("music volume")
vbar value Preference("voice volume")

纵向排列子组件的不可是垂直方框(box)。vbox不接受参数,可以拥有下列特性:

UI可视组件作为子组件添加到vbox:

screen vbox_test():
vbox:
text "Top."
text "Bottom."

视口(viewport)是界面中的某块区域,可以使用鼠标滚轮或者滚动条进行滚动。视口可以用于显示某些比界面更大的东西。其使用以下特性:

  • child_sizelink

    待渲染子组件的尺寸,是一个 (xsize, ysize) 形式的元组。 该值通常是省略的,子组件可以自己计算尺寸。如果所有组件的size特性都为空,则使用子组件的尺寸信息。

  • mousewheellink

    该值可以是下列之一:False忽略鼠标滚轮。(默认值。)True垂直滚动。“horizontal”水平滚动。“change”垂直滚动视口,只有使用change操作才能触发视口移动。如果change为空,鼠标滚轮时间会传给其他用户接口。(例如,如果给定change的值,并在viewport语句之前放了 key "viewport_wheeldown" action Return() ,当视口滚动到底部时就会触发界面返回。)“horizontal-change”与change模式一同使用,决定水平滚动的情况。

  • draggablelink

    若为True,鼠标拖动就能滚动视口。 该项可以设置为 variant,这样视口也可以拖动。(例如,设置为 draggable "touch"。)

  • edgescrolllink

    当鼠标到达视口边缘时,控制滚动行为。若该值非空,应该是一个2元或者3元的元组。元组内第一个元素是从视口边缘到edgescroll开始生效处的距离,单位是像素。元组内第二个元素是滚动率最大值,单位是像素每秒。如果元组内存在第三个元素,它是一个调整滚动速度的函数,取决于鼠标指针与界面边缘的距离。函数入参为一个介于-1.0和1.0之间的数值,返回一个同样区间内的数值。函数默认值与输入相同,且按比例进行滚动。函数返回值是-1.0还是1.0,取决于输入值的符号,并实现匀速滚动。

  • xadjustmentlink

    ui.adjustment() 对象,用作视口x轴的调整。当该特性省略时,就会创建一个新的adjustment对象。

  • yadjustmentlink

    ui.adjustment() 对象,用作视口y轴的调整。当该特性省略时,就会创建一个新的adjustment对象。

  • xinitiallink

    视口初始水平偏移量。其可以是一个整数,表示像素数;也可以是一个浮点数,表示一个可能的偏移比例。

  • yinitiallink

    视口初始垂直偏移量。其可以是一个整数,表示像素数;也可以是一个浮点数,表示一个可能的偏移比例。

  • scrollbarslink

    若不为None,滚动条会添加到视口上。scrollbar会创建一个单边布局(layout),并把视口放在单边的中间。如果 scrollbars 的值是 “horizontal”,就在视口上创建一个水平的滚动条。如果 scrollbars 的值是 “vertical”,就在视口上创建一个垂直的滚动条。如果 scrollbars 的值是 “both”,水平和垂直滚动条都会被创建。若 scrollbars 不为None,viewport 将使用以下特性前缀:前缀为 viewport_ 的特性穿给视口。前缀为 side_ 的特性传给side。前缀为 scrollbar_ 的特性传给水平滚动条。前缀为 vscrollbar_ 的特性传给垂直滚动条。也能使用没有前缀的特性。 位置样式特性 会传给side,其他无前缀特性会应用到视口。

  • arrowkeyslink

    若为True,视口可以使用上下左右方向键进行滚动。这种情况下方向键的作用优先于方向键的其他功能。当视口到达限制时,方向键会改变焦点。

  • pagekeyslink

    若为True,视口可以使用翻页键向上和向下滚动。这会让翻页键原本的功能失效。原本的功能是回滚和前进。

除此之外,视口还使用以下特性。

视口含有一个子组件。如果实际上提供的子组件并非一个,那就会创建一个固定位置布局容纳所有子组件。

想让一个视口可滚动,最好的办法通常是声明一个视口id,然后使用 XScrollValue()YScrollValue()

screen viewport_example():
side "c b r":
area (100, 100, 600, 400)
viewport id "vp":
draggable True
add "washington.jpg"
bar value XScrollValue("vp")
vbar value YScrollValue("vp")

vpgrid(viewport grid)将视口与网格(grid)结合为单个可视组件。vpgrid(如grid一般)包含多个子组件,并且经过优化可使视口只渲染指定的子组件。

vpgrid假设所有子组件尺寸相同,并基于第一个子组件确定实际绘制大小。若某个vpgrid渲染结果不正确,请检查并确保所有子组件的尺寸是相同的。

vpgrid必须至少给定 cols 和 rows 特性。如果有其中之一省略或者是None,另一个特性就会根据子组件的尺寸、空间和数量自动决定。

vpgrid拥有下列特性:

  • colslink

    网格(grid)的列数。

  • rowslink

    网格(grid)的行数。

  • transposelink

    若为True,单位网格按列填充。该特性的默认值取决于 cols 和 rows 的特性。如果 cols 出现,单元网格会先按列填充,否则按行填充。

除此之外,vpgrid使用所有 视口 可使用的特性,以及下列特性:

当指定 scrollbar 特性时,有前缀的特性会以类似视口(viewport)的方式传给vpgrid。 (前缀为 viewport_ 的特性也会传给vpgrid。)

screen vpgrid_test():
vpgrid:
cols 2
spacing 5
draggable True
mousewheel True
scrollbars "vertical"
# 由于我们有scrollbar,所以我们必须设置“边”的位置,而不需要设置vpgrid。
xalign 0.5
for i in range(1, 101):
textbutton "Button [i]":
xysize (200, 50)
action Return(i)

window是个包含背景的窗口,用于显示游戏内对话。其拥有下列特性:

window含有一个子组件。如果实际上提供的子组件并非一个,那就会创建一个固定位置布局容纳所有子组件。

screen say(who, what):
window id "window"
vbox:
spacing 10
text who id "who"
text what id "what"
界面和界面语言
https://vilstia.pages.dev/posts/游戏开发/renpy/界面和界面语言/
作者
琴泠
发布于
2026-04-11
许可协议
CC BY-NC-SA 4.0