变换 link
变换(transform)可以按顺序依次使用,将一个 可视组件 变为另一个可视组件。 总共有多种类型的变换,也有多种方式创建变换。 内建的变换常用于控制界面上某个对象的位置,而用户自定义的变换可以触发更复杂的效果,比如移动、缩放和旋转,甚至复杂的色彩效果。
在scene和 show 语句后使用at分句就能应用各种变换。
下面样例中对图像 eileen happy
应用了 right
变换。:
show eileen happy at right
可以同时应用多个变换,不同变换之间用英文逗号分隔。这些变换从左到右依次应用。
show eileen happy at halfsize, right
在Python中对可视组件应用变换 link
若要在Python中对可视组件 d
引用变换 t
有好几种方法:
最为通用也最推荐的方法是,使用
At(d, t)
(下面有样例)。这种方法适用于所有变换。d(child=t)
适用于所有 ATL变换。t(d)
适用于 Python变换,以及不需要坐标作为参数的ATL变换。
- At(d, *args) link
对指定的源可视组件 d ,将 args 中所有变换应用于该组件。变换的应用顺序是从左到右,所以最外层的变换效果是最右边的入参。
transform birds_transform: xpos -200 linear 10 xpos 800 pause 20 repeat image birds = At("birds.png", birds_transform)
Note
如果某些变换没有传入需要的参数,变换结果可能会导致无法正常显示。 这种情况下需要检查使用 transform语句 定义的变换到底需要什么参数。
Note
变换结果可能还是一个变换,可以进一步应用于另一个可视组件(及其子组件); 这种情况下ATL变换依然可以如其他变换一样使用,不影响其子组件。
内建变换 link
Ren’Py附带了一些默认定义好的变换。这些变换定义了界面上的位置信息。这里有一个默认变换下图像位置的描述:
+-----------------------------------------------------------+
|topleft, reset top topright|
| |
| |
| |
| |
| truecenter |
| |
| |
| |
| |
offscreenleft|left center, default right|offscreenright
+-----------------------------------------------------------+
offscreenleft
和 offscreenright
变换会让图像显示在界面之外。这两个变换可以用于将物体从界面移除(记得之后隐藏这些物体,并确认他们不再消耗系统资源)。
这些变换(transform)的详细信息如下:
- center link
水平居中,并与界面底部对齐。
- default link
水平居中,并与界面底部对齐。default可以通过
config.default_transform
重定义,这样show和scene语句显示的图片默认位置也会改变
- left link
与界面左下角对齐。
- offscreenleft link
将可视组件置于界面左外侧,与界面底部对齐。
- offscreenright link
将可视组件置于界面右外侧,与界面底部对齐。
- reset link
重置变换。将可视组件放置在界面左上角,并清除一切缩放、旋转及其他效果。
- right link
与界面右下角对齐。
- top link
水平居中,与界面顶部对齐。
- topleft link
与界面左上角对齐。
- topright link
与界面右上角对齐。
- truecenter link
水平和垂直都居中。
动画和变换语言 link
动画和变换语言(简称ATL)提供了一种高级方式,便于创建动画、界面内移动可视组件、设置组件位置、应用各种变换(等。 ATL语言可以根据时间变化实现效果,也可以根据事件类消息做出响应。
在Python中,与ATL变换等效的是 Transform()
类组件。目前没有办法通过编程创建一个ATL变换效果。
可以使用 transform语句 创建ATL变换对象。创建结果可用作可视组件(可能没有能被看到的子组件所以透明)。
ATL变换对象可以使用 add 传入某个界面,或者使用 show expression语句 或 renpy.show()
函数直接显示。
Ren’Py脚本语句 link
ATL可以包含在Ren’Py脚本语句中。
transform语句 link
transform
语句创建了一个变换(transform)效果,可以在某个at分句中使用。transform语句的语法如下:
atl_transform ::= "transform"qualname
( "("parameters
")" )? ":"atl_block
transform语句必须在 初始化阶段 运行。 定义transform可能需要一个参数列表,使用方式与Python函数类型。 有一些类型参数暂时禁止使用,未来可能会开放:
只有固定位置参数
没有默认值的关键词参数
可变的固定位置参数(
*args
)可变的关键词参数(
**kwargs
)
只有所有参数都赋值之后,创建的Transfor对象才能用作变换。
请参考: ATL的柯里化和部分入参传递
qualname 必须是一个使用英文标点“.”分割的Python标识符。使用ATL创建的transform与 qualname 绑定, 如果存在 store 则保存在对应存储空间中。
transform left_to_right:
xalign 0.
linear 2 xalign 1.
repeat
transform ariana.left:
xalign .3
transform animated_ariana_disp:
"ariana"
pause 1.
"ariana_reverse"
pause 1.
repeat
创建出的对象既是变换也是可视组件,但不支持 image
语句。
因为它以变量(或常量)形式创建,与命名空间 images 中的对象不同。
带ATL语句块的image语句 link
使用ATL的另一种方法是,在 images 语句中包含ATL语句块。这将某个图像与给定的transform绑定。由于没有办法向该transform传入参数,所以只在transform自身定义了某个动画的情况下才有用。 带ATL语句块的image语句语法如下:
atl_image ::= "image"image_name
":"atl_block
image animated_ariana_img:
"ariana"
pause 1.
"ariana_reverse"
pause 1.
repeat
带ATL语句块的scene和show语句 link
最后一种使用ATL的方法是,包含在 scene
或者 show 语句中。这种方法可以通过ATL改变图像。
atl_scene ::=stmt_scene
":"atl_block
atl_show ::=stmt_show
":"atl_block
show eileen happy:
xalign 1.
scene bg washington:
zoom 2.
ATL语法和语义 link
ATL语句可能是单行的,也可能是多行组成的语句块(block)。 除了后面会提到的少数例外,ATL语句块中的语句按从上到下的顺序执行。
如果某个ATL语句需要计算某个表达式,那么对应的整个变换首次执行时(例如使用 show
语句或将该变换显示为某个界面的一部分时)将计算该表达式,
而不是执行某部分ATL语句时才计算。
一个ATL语句块(block)由一个或多个逻辑行组成,使用相同的缩进量。每个ATL语句块中的逻辑行都必须包含一条或多条ATL语句。
总共有两种ATL语句:简单ATL语句和复杂ATL语句。简单语句不使用ATL语句块。单条逻辑行就可能包含一条或多条ATL语句,使用英文逗号分隔。复杂语句会包含语句块(block)。复杂语句的第一行会以英文冒号(
":"
)结尾:默认情况下,语句块(block)里会从第一条语句开始顺序执行所有语句。当整个语句块达到结尾时执行就会被终止。time语句会改变这种执行逻辑,详见后面的段落。
当语句块(block)中所有语句都终止时,语句块的执行也就被终止了。
如果ATL语句需要某个表达式赋值,只能在transform初次加入场景列表时进行赋值。(比如使用
show
语句或者某个界面显示展示部分变换时。)
下面列出各种ATL语句。
单行contains语句 link
单行contains语句可以计算一个简单表达式,并得到一个 可视组件 。
atl_contains ::= "contains" expression
此语句会把当前ATL变换的某个子组件设置(或替换)成表达式计算结果,用作动画。
transform an_animation:
"1.png"
pause 2
"2.png"
pause 2
repeat
image move_an_animation:
contains an_animation
# 如果我们不使用contains语句,
# 就会一直处于循环中并不能抵达这里
xalign 0.0
linear 1.0 yalign 1.0
与变换表达式语句相比,可视组件语句 定义更明晰,但其可以使用 transition 来替换子组件。 contains语句适合用在某个ATL语句块中容纳另一个变换效果,而不是单纯复用某个变换的代码块。
数值语句 link
数值语句由一个简单表达式构成,该表达式可以计算出一个整数或一个浮点数。 其是“pause”的一个简略版。
atl_number ::= "pause"? simple_expression
数值语句用于指定一个固定秒数的暂停。
image atl example:
# 显示logo_base.png。
contains "logo_base.png"
# 暂停1.0秒。
pause 1.0
# 显示logo_bw.png,使用dissolve转场。
"logo_bw.png" with Dissolve(0.5, alpha=True)
# 暂停3秒。
3
repeat
特性值语句 link
该语句可以将一个或多个变换特性设置为某个新的值。
atl_properties ::= atl_property
+
atl_property ::=transform_property
simple_expression
特性值语句先指定一些特性名称,并对每项特性都设置一个值。 变换特性 中的变换特性列表详细说明了每个特性的含义及使用的值类型。
transform rightoid:
xalign .9
transform ariana.left:
xanchor .3 xpos 100
插值语句 link
插值语句主要用于获取平滑的动画效果。
atl_interp ::= ((warper
simple_expression
) | ("warp"simple_expression
simple_expression
)) (atl_interp_target
+ | (":"atl_interp_target
+ ))
atl_interp_target ::= (atl_property
+ ("knot"simple_expression
)* ) |atl_transform_expression
| "clockwise" | "counterclockwise" | ("circles"simple_expression
)
下面是一些插值语句的样例:
show logo base:
# 在界面右上角显示logo。
xalign 1.0 yalign 0.0
# 耗时1秒,将logo移动到最左侧。
linear 1.0 xalign 0.0
# 耗时1秒,将logo移动到界面正中心。移动时的使用ease缓动函数。
ease 1.0 truecenter
# 设置旋转锚点。
anchor (0.5, 0.5)
# 耗时2秒,让logo按顺时针方向做圆周旋转,最终到达界面正上方。
linear 2.0 yalign 0.0 clockwise circles 3
# 让logo按照指定样条的路径,在界面中移动。
linear 2.0 align (0.5, 1.0) knot (0.0, .33) knot (1.0, .66)
# 同时修改xalign和yalign的值。
linear 2.0 xalign 1.0 yalign 1.0
# 与上一步相同,但使用语句块形式。
linear 2.0:
xalign 1.0
yalign 1.0
插值语句的第一部分用于选择time-warp函数。即,将线性时间转为非线性时间,关于warper的信息详见 warpers 。 可以使用在ATL注册的warp类函数名,或者使用关键词“warp”开头的某个表达式代表的函数。 无论使用的是哪种函数,后面跟着的数字表示总体消耗时间,单位为秒。
transform builtin_warper:
xpos 0
ease 5 xpos 520
init python:
def my_warper(t):
return t**4.4
define my_warpers = [my_warper]
transform accessed_as_function:
xpos 0
warp my_warpers[0] 5 xpos 520
warp my_warper 3 xpos 100
整个插值语句的持续时长由给定的时间决定,至少为1帧。
指定的 变换特性 会逐渐逼近终值,并在插值语句结尾达到该终值。 具体的细节有以下几种:
如果终值后面还跟着一个或多个节点(knot),表示运动路径是样条。 初始值和终值分别是样条的起点与终点,knot则是样条的控制节点。 四次曲线只使用一个knot,贝塞尔曲线使用两个knot,Carmull-Rom曲线则使用三个或更多knot。 前两种情况中,knot都是单纯的控制节点。 而Catmull-Rom曲线中,只有首尾两个knot是控制节点(通常不在曲线上),其他knot则都在曲线路径上。
如果插值语句中包含一个“clockwise”或“counterclockwise”从句,表示使用圆周运动。 Ren’Py处理圆周运动时,首先比较起点与终点位置(通常使用
pos
、align
、angle
和radius
设置), 然后找到极坐标原点(通常使用around
设置)。接着计算指定方向需要旋转的角度值,单位为度。 如果出现了“circle”从句,Ren’Py则会加上对应数量的整圈。其他情况下,会对起点和重点的坐标进行线性插值。
如果某个 变换表达式语句 中只有一条特性(property)语句,也可以进行插值计算。 起始值就是ATL变换中对应特性的值,跟直接设置起点的值效果相同。
warper后面可以跟一个英文冒号(:)。这种情况下,warper后可能会有一个或多个如上阐述的从句。 这样做可以让ATL可以同时对多个特性进行插值。
pass语句 link
atl_pass ::= "pass"
pass
语句是一个简单语句,不会触发任何效果:一种 no-op 。
pass语句可以用于分隔其他语句。比如出现两套choice语句的时候,如果不用pass语句,选项会混在一起。
pass语句还可以用在一些语法层面需要出现语句块,但创作者只想要空着的地方,比如某些选项语句后面必须写点什么。
(译者注:pass就是脚本中的占位符。空着不写会报错,写个pass就能运行了。)
repeat语句 link
repeat
语句是一种简单语句。脚本执行到repeat时会跳转到包含repeat的语句块的开头,并重新开始执行。
atl_repeat ::= "repeat" (simple_expression
)?
如果repeat中出现了一个表达式,该表达式可以计算出一个整数。这个整数就是整个语句块(block)重复执行的次数。
(repeat 2
表示语句块最多会执行2次,repeat 1
则不会有重复执行的效果。)
repeat语句必须是一个语句块(block)的最后一个语句:
show logo base:
xalign 0.0
linear 1.0 xalign 1.0
linear 1.0 xalign 0.0
repeat
block语句 link
block
语句包含ATL语句块(block)。
atl_block_stmt ::= "block" ":"
atl_block
block语句用于对需要重复运行的语句分组:
label logo base:
alpha 0.0 xalign 0.0 yalign 0.0
linear 1.0 alpha 1.0
block:
linear 1.0 xalign 1.0
linear 1.0 xalign 0.0
repeat
parallel语句 link
parallel
语句用于定义一个可以并行执行的ATL语句块的集。
atl_parallel ::= ("parallel" ":"
atl_block
)+
parallel语句会将语句块(block)中连续出现的多个parallel项都放入一个并行集之中。当整个语句块中所有语句都执行完后,parallel语句才会终止。
语句块中的所有并行语句都应各自独立,并使用不同的 变换特性。当两个并行分支修改了同一项特性(property),会产生无法预料的结果。
show logo base:
parallel:
xalign 0.0
linear 1.3 xalign 1.0
linear 1.3 xalign 0.0
repeat
parallel:
yalign 0.0
linear 1.6 yalign 1.0
linear 1.6 yalign 0.0
repeat
choice语句 link
choice
语句定义了一个所有可选项的集合。Ren’Py会根据玩家的选择,执行对应选项相关的ATL语句块(block),之后跳转到choice语句块结束处。
atl_choice ::= ("choice" (simple_expression
)? ":"atl_block
)+
choice语句会将语句块(block)中连续出现的多个choice选项都放入一个选项集之中。如果选项后面出现一个简单表达式,这个表达式的值应该是一个浮点数,表示对应选项的权重;如果没有权重表达式,默认值为1.0。
image eileen random:
choice:
"eileen happy"
choice:
"eileen vhappy"
choice:
"eileen concerned"
pause 1.0
repeat
在choice语句块内部使用 pass
语句可以生成一个空的choice语句块。
animation语句 link
使用 animation
语句时,必须将其放在整个ATL语句块的开头,告诉Ren’Py该语句块要使用动画时间轴。
atl_animation ::= "animation"
与普通的显示时间轴相比,在带有相同标签(tag)的图像(image)或界面(screen)开始显示的那一刻,animation时间轴就将进行计时并被所有相同标签(tag)的图像和界面共享。 animation时间轴常用于动画过程中的图像替换。例如:
image eileen happy moving:
animation
"eileen happy"
xalign 0.0
linear 5.0 xalign 1.0
repeat
image eileen vhappy moving:
animation
"eileen vhappy"
xalign 0.0
linear 5.0 xalign 1.0
repeat
label start:
show eileen happy moving
pause
show eileen vhappy moving
pause
这个例子中,艾琳的立绘表情将在第一个 pause 语句处改变,但她的位置不会改变。 因为两个动画使用相同的animation时间轴,避免了更换立绘后出现图像位置不连续。 不使用 animation 语句的话,用户通过点击鼠标或屏幕后,角色的立绘位置将发生一次重置。
on语句 link
on
语句会定义一个事件处理器(handler)。
atl_on ::= "on"name
[ ","name
] * ":"atl_block
on
语句会将语句块(block)中连续出现的多个on项都放入一个事件集之中。on语句可以只处理某一个事件名,或者使用逗号分隔的事件名列表。
on语句用于处理各种事件(event)。当某个事件被处理后,其他的事件处理就会停止,并且会立即进入新事件的处理流程。当某个事件处理器没有新的待处理事件,就会产生 default
事件(已经处理 default
事件的情况除外)。
on语句的执行不会自然终止。(但是其可以被time语句,或者关联的事件处理器终止。)
生成任意事件的方法详见event语句部分,以及 外部事件 中的原生事件列表。
show logo base:
on show:
alpha 0.0
linear .5 alpha 1.0
on hide:
linear .5 alpha 0.0
transform pulse_button:
on hover, idle:
linear .25 zoom 1.25
linear .25 zoom 1.0
变换表达式语句 link
变换表达式语句可以包含另一个ATL变换,并用作自身ATL语句块的一部分。
atl_transform_expression ::= simple_expression
这种语句只有在ATL变换自身 没有 子组件时才有效。否则,同样的语句会被当作 可视组件语句 处理。 变换表达式语句中的内容会替换变换名,并执行对应的变换。
transform move_right:
linear 1.0 xalign 1.0
image atl example:
# 显示logo_base.png
"logo_base.png"
# 运行变换move_right
move_right
可视组件语句 link
可视组件语句通常是一个简单的Python表达式,可以计算出一个 可视组件 对象。 可视组件语句后面也可能会有一个从句,即另一个简单表达式。
atl_displayable ::=simple_expression
("with"simple_expression
)?
该语句用于设置或替换某个变换的子组件。
如果后面有 with
从句,后面的第二个表达式计算结果会用作 转场 效果,并用于新旧两个子组件的切换过程。
需要注意的是,并非所有转场都能正常使用。具体参考 字典转场(Dict Transitions) 、 move-
和:var:ease- <ease> 。
image atl example:
# 显示logo_base.png。
"logo_base.png"
# 暂停1.0秒。
1.0
# 显示logo_bw.png,使用dissolve转场效果。
"logo_bw.png" with Dissolve(0.5, alpha=True)
Warning
如果传入无子组件的变换对象,可能会让整个变换变成透明且无效。 传入无子组件的ATL变换可能会被当作 变换表达式语句,产生与预期不同的效果。
如果表达式计算出的ATL变换 包含 子组件,那么整个ATL语句块会等到所有子组件内的ATL代码都执行完之后再继续向下执行。
contains语句块 link
contains语句块,类似于 单行contains语句,可以设置变换的子组件,但方式不同。
atl_counts ::= "contains" ":"
atl_block
一个或多个contains语句块会被分组,并放在一个 Fixed()
组件中,设置为该变换的子组件。
每个语句块都必须定义一个可用的可视组件,否则会报错。 所有contains语句会立刻并行执行,并不会等待所有子组件内的代码都执行完毕才执行下一条contains。
image test double:
contains:
"logo.png"
xalign 0.0
linear 1.0 xalign 1.0
repeat
contains:
"logo.png"
xalign 1.0
linear 1.0 xalign 0.0
repeat
function语句 link
function
语句允许ATL使用Python代码。
atl_function ::= "function" simple_expression
这些函数与 Transform()
具有相同的入参和返回结果:
第一个入参是一个transform对象。可以设置该对象的 变换特性。
第二个入参是显示时间轴,表示函数开始执行到现在经过的秒数。
第三个入参是动画时间轴,表示具有相同标签(tag)的对象在整个界面上已存在的秒数。
如果函数返回一个数值,其会在数值对应的时间(秒)后再次被调用。(0秒表示尽可能快地调用该函数。)如果函数返回None,主控流程会跳到下一个ATL语句。
除了修改第一个入参中的Transform对象之外,该函数不应产生副作用。 并可以在任意时间传入任意值并调用,能配合预加载功能。
注意,function
不是一个变换特性,并且其跟 Transform()
的 function 参数也不完全一致。
init python:
def slide_vibrate(trans, st, at, /):
if st > 1.0:
trans.xalign = 1.0
trans.yoffset = 0
return None
else:
trans.xalign = st
trans.yoffset = random.randrange(-10, 11)
return 0
label start:
show logo base:
function slide_vibrate
pause 1.0
repeat
time语句 link
time
语句是一种控制语句。
atl_time ::= "time" simple_expression
其包含一个简单表达式,可以算出一个时间点,单位为秒。这个时间点表示其所在语句块(block)从开始执行到time语句结束的总时长。 当time语句中给定的“time”结束后,后面的语句才会开始执行。在上一个语句还在执行的情况下,这种控制转换依然会执行,也能强行终止任意优先级的语句。
time语句隐含了一个pause语句,表示暂停无限长时间。这表示如果主控流程不能抵达time语句处,它就会保持等待直到time语句获取流程控制权。
当一个语句块中存在多个time语句时,它们各自的结束时间点必须按顺序严格递增。
image backgrounds:
"bg band"
xoffset 0
block:
linear 1 xoffset 10
linear 1 xoffset 0
repeat # 主控流程永远无法主动退出循环
time 2.0
xoffset 0
"bg whitehouse"
time 4.0
"bg washington"
event语句 link
event
语句是一个简单语句,其会使用给定的名称产生一个事件(event)。
atl_event ::= "event" name
当在某个语句块(block)运行过程中出现某个事件(event)时,语句块会检查自身是否存在对应事件名的处理器(handler)。如果处理器存在,主控流程会切换到对应的事件处理器。否则,事件会广播至所有事件处理器。
外部事件 link
下列事件会在ATL变换中自动触发:
start
一种伪事件,进入
on
语句时触发,前提是没有更高优先级的事件出现。show
使用
show
或者scene
语句显示transform,并且给定标签(tag)没有对应已显示的图像时触发。replace
使用
show
语句中的transform根据给定标签(tag)替换某个图像时触发。hide
使用
hide
语句或等效的python语句中的transform时触发。replaced
transform被另一个transform替换时触发。原transform的图像实际上并不会隐藏或移除,直到整个ATL语句块(block)执行完。
hover
、idle
、selected_hover
、selected_idle
、insensitive
、selected_insensitive
当包含此transform的按钮或者被此transform包含的按钮,出现对应的状态名称时触发。
ATL的柯里化和部分入参传递 link
使用 transform语句 定义的ATL变换可以设置多种不同的入参列表。 如同调用函数一样调用ATL变换时,返回结果依然是一个transform,入参则可以改变原transform中同名参数的值。
例如:
transform screamer(child, screamee, wait_time=2, flash_time=.1):
child
pause wait_time
screamee
pause flash_time
child
# 这样写不会报错(类似于引用Python函数返回结果)。
define shorter_screamer = screamer(wait_time=1)
define eileen_excited_screamer = screamer(screamee="eileen excited", flash_time=.2)
label start:
show hhannahh happy at screamer(screamee="hhannahh surprised", wait_time=1.5)
"这是一种方法。"
show eileen vhappy at eileen_excited_screamer
"这是另一种方法。"
show patricia sad at eileen_excited_screamer(screamee="patricia wow")
"并且你也可以这样做。"
需要注意,变换 shorter_screamer
虽然源自 screamer
,但不能直接像 show eileen at screamer
这样直接用。
因为其 screamee
参数未赋值。
还要注意,类似脚本标签(label)和界面(screen)定义,使用 transform语句 定义的transform的入参默认值, 是在transform 被调用 时才计算的,而不是 被定义 时就计算好的。
总之,transform只有在调用另一个变换(例如上例中的 shorter_screamer
或部分入参传递)时,才会计算所有入参的默认值。
无论默认值来自原始的transform(比如 shorter_screamer
的 flash_time 参数或部分入参传递的 wait_time 参数),
还是来自更早执行的脚本中的调用(比如 shorter_screamer` 中的 wait_time 参数或部分入参传递的 screamee 和`flash_time` 参数)。
特殊child参数 link
如果某个ATL变换有一个入参名为“child”,并且该入参获得了一个值,那么将 无视该入参值的类型和赋值方式 , 该变换的子组件将被设置为child参数的值。 (无视入参值类型和赋值方式是指,不需要考虑参数是固定位置入参是还是关键词入参,也不需要考虑该参数有默认值还是要求必须重新赋值。)
需要注意,child入参的默认值不会生效,还是需要从外部传入一个新的值。
另外,ATL变换用作一个transform时,默认不会将 child=
作为关键词参数传递并设置目标的child,除非目标有个同名的child入参。
例如,下面的脚本能在child与另一个可视组件之间来回切换:
transform lucy_jump_scare(child):
# child的值会隐式设置为transform的子组件。
pause 5
# “jump scare”式惊吓。
"lucy mad"
pause .2
# 再显示原来的子组件。
child
还可以在 contains
语句块中放置原来的子组件:
transform marquee(width, height=1.0, duration=2.0, child=None):
xcenter 0.5
ycenter 0.5
crop (0, 0, 0.5, 500)
contains:
child
xanchor 0.0 xpos 1.0
linear duration xanchor 1.0 xpos 0.0
old_widget 和 new_widget 两个“关键词限定”入参(即不能用于固定位置入参)在 ATL转场 中有特殊用法。
warpers link
warper是一类函数,其可以改变插值语句中用到的时间值。他们将时间t转换为t’,t和t’都是浮点数,t会将给定的时间值归一化为0.0到1.0。 (如果该语句给定的原时长是0,那运行时t就是1.0。) t’的初始取值范围也是0.0到1.0,不过可以超出这个范围。 以下warper都是默认定义好的。
pause
暂停,然后跳变成新值。如果
t == 1.0
,则t' = 1.0
;否则t' = 0.0
。linear
线性插值。
t' = t
ease
开头慢,中间加速,之后又减速。
t' = .5 - math.cos(math.pi * t) / 2.0
easein
开头快,然后减速。
t' = math.cos((1.0 - t) * math.pi / 2.0
easeout
开头慢,然后加速。
t' = 1.0 - math.cos(t * math.pi / 2.0)
除此之外,Robert Penner的easing函数都是支持的。为了避免与上面的几个函数名重复,有些函数名字修改过。这些标准函数的图像可以在这个网站上查看 http://www.easings.net/
Ren’Py 函数名 |
easings.net 函数名 |
---|---|
ease_back |
easeInOut_back |
ease_bounce |
easeInOut_bounce |
ease_circ |
easeInOut_circ |
ease_cubic |
easeInOut_cubic |
ease_elastic |
easeInOut_elastic |
ease_expo |
easeInOut_expo |
ease_quad |
easeInOut_quad |
ease_quart |
easeInOut_quart |
ease_quint |
easeInOut_quint |
easein_back |
easeOut_back |
easein_bounce |
easeOut_bounce |
easein_circ |
easeOut_circ |
easein_cubic |
easeOut_cubic |
easein_elastic |
easeOut_elastic |
easein_expo |
easeOut_expo |
easein_quad |
easeOut_quad |
easein_quart |
easeOut_quart |
easein_quint |
easeOut_quint |
easeout_back |
easeIn_back |
easeout_bounce |
easeIn_bounce |
easeout_circ |
easeIn_circ |
easeout_cubic |
easeIn_cubic |
easeout_elastic |
easeIn_elastic |
easeout_expo |
easeIn_expo |
easeout_quad |
easeIn_quad |
easeout_quart |
easeIn_quart |
easeout_quint |
easeIn_quint |
可以通过只读模块 _warper
访问这些warper效果。该模块包含了上述所有函数。
在Ren’Py内置效果中使用时间warp函数很有用,比如可以这样用:
with Dissolve(1, time_warp=_warper.easein_quad)
我们可以在一个 python early
语句块中,使用 renpy.atl_warper
装饰器定义新的warper函数。定义warper函数文件需要在使用那个函数的其他任何文件之前被处理。定义的代码如下:
python early hide:
@renpy.atl_warper
def linear(t):
return t
替换变换 link
某个ATL变换、内建变换或使用 Transform
定义的变换对象被同类变换替换时,
同名特性的值会从前一个变换继承到新的变换。不同类型的变换无法继承。
如果 show语句 中的at关键字后列出了多个变换待替换,则新变换列表从后往前依次替换,直到新替换变换列表全部换完。例如:
show eileen happy at a, b, c
"我们稍等一下。"
show eileen happy at d, e
e
变换替换了 c
, d
变换替换了 b
,而没有变换会替换 a
。
替换时,旧变换的特性值由新变换继承。如果旧变换正处于动画中,则新变换继承的可能是中间的某个值。例如:
transform bounce:
linear 3.0 xalign 1.0
linear 3.0 xalign 0.0
repeat
transform headright:
linear 15 xalign 1.0
label example:
show eileen happy at bounce
pause
show eileen happy at headright
pause
这个例子中,图像会左右弹跳,直到用户点击鼠标。
当用户点击鼠标后, bounce
中的 xalign
特性值将被 headright
继承。
精灵在x轴方向坐标移动的初始值,即是用户点击鼠标时的值。
位置相关特性(包括 xpos
、ypos
、xanchor
和 yanchor
,以及等效的:tpref:xalign、radius
和 angle
))继承时有一项特殊规则:
子组件设置的值会覆盖父组件的值。这样设计是考虑到可视组件往往只有一项位置信息,需要优先保证设置的值不受影响。
对位置特性的设置有多种方式,例如,xalign
会同时设置xpos和xanchor。
最后,如果某个 show
语句不包含 at
从句,则不需要搞特性值继承问题。若要重置所有变换特性,可以先隐藏再显示对应的可视组件。
若要中断动画效果,可以这样:
show eileen happy at some_animation
"Wow, so this is what antigravity feels like !"
show eileen:
pass
"But I'm happy when it settles down."
Transform类 link
ATL变换在Python中等效于一个Transform对象。
- class Transform(child=None, function=None, **properties) link
创建一个Transform对象,并将各种操作应用到其子组件,操作包括:剪裁、旋转、缩放和alpha混合等。 一个Transform对象的字段一一对应 变换特性 ,并都将应用到子组件。
- child
应用变换的子组件。
- function(trans: Transform, st: float, at: float, /) int | None link
若不是None,这是渲染变换效果时调用的函数。调用这个函数时使用3个固定位置入参:
Transform对象。
显示时间轴,单位为秒。
动画时间轴,单位为秒。
函数会返回一个延迟时间,单位为秒。在运行延迟时间之后这个函数会被再次调用。如果延迟时间是None,则会在下次互动之后立刻调用。
该函数除了修改第一个入参的变换对象之外不应有其他副作用,并且要求可以在任何时间点使用任何值调用以配合预加载。
其他关键词入参都会作为对应变换特性的值。 绘制变换效果时,对应的变换特性都会根据入参设置值,但在变换对象创建后不再更改。 使用
function
参数传入的函数或调用update()
方法,可以改变对应的变换特性。其他参数被视为设置变换特性的值。
- hide_request link
当function函数被调用时,这项会被设置为True,标识变换效果被隐藏。
- hide_response link
如果hide_request为True,这项会被设置为False,防止变换效果被隐藏。
- set_child(child) link
使用一个新的 child 调用这个方法,child 成为变换的子组件。
- update() link
当变换特性(property)字段在 function 参数指定的回调方法之外被更新时,这个方法会被调用,确保修改生效。
可调用对象用作变换 link
Finally, simple Python callables can be used as transforms. These callables should take a single displayable as an argument, and return a new Displayable. For example 最后,Python中的可调用对象可以用作变换。这些可调用对象必须能使用 可视组件 作为入参, 并且能返回一个新的可视组件。例如:
init python:
# 这是一个使用right和left两个默认变换的自定义变换。
def right_or_left(d):
if switch:
return At(d, right)
else:
return At(d, left)
某些内建对象可以也符合入参为可视组件并返回可视组件的要求,例如 Flatten()
,也可以直接用作变换。