Трансформации

Трансформации используются для превращения одного отображаемого элемента (displayable) в другой. Существует несколько видов трансформаций и различные способы их создания. Встроенные трансформации используются для контроля расположения изображения на экране, в то время как пользовательские трансформации могут вызывать более сложные эффекты, такие как движение, масштабирование, вращение, вплоть до сложных цветовых эффектов.

Быстрый старт

Трансформации можно применять к изображениям, передавая их в предложение at инструкций show или scene. Следующий код применяет трансформацию right к изображению eileen happy:

show eileen happy at right

Можно применять несколько трансформаций, разделяя их запятыми. Эти трансформации применяются слева направо.

show eileen happy at halfsize, right

Простая ATL-трансформация:

transform slide_right:
    xalign 0.0
    linear 1.0 xalign 1.0

label start:
    show eileen happy at slide_right
    pause

Показ трансформаций с помощью Python:

label start:
    $ renpy.show("eileen happy", at_list=right)
    pause

Простая трансформация на Python с использованием At():

init python:
    def show_eileen_rotated():
        rotated = Transform(rotate=45)
        show_stmt = At("eileen happy", rotated)
        renpy.show("eileen", what=show_stmt)

label start:
    $ show_eileen_rotated()
    pause

Встроенные трансформации

Ren'Py поставляется с рядом трансформаций, определенных по умолчанию. Эти трансформации позиционируют объекты на экране. Вот изображение того, как каждая встроенная трансформация будет позиционировать изображение.

              +-----------------------------------------------------------+
              | topleft, reset               top                 topright |
              |                                                           |
              |                                                           |
              |                                                           |
              |                                                           |
              |                          truecenter                       |
              |                                                           |
              |                                                           |
              |                                                           |
              |                                                           |
offscreenleft | left                   center, default              right | offscreenright
              +-----------------------------------------------------------+

Трансформации offscreenleft и offscreenright размещают изображения за краями экрана. Эти трансформации можно использовать для перемещения объектов за пределы экрана (не забудьте скрыть их после этого, чтобы они не потребляли ресурсы).

Список трансформаций:

center

Центрирует по горизонтали и выравнивает по нижнему краю экрана.

default

Центрирует по горизонтали и выравнивает по нижнему краю экрана. Это можно переопределить через config.default_transform, чтобы изменить стандартное размещение изображений, показываемых с помощью инструкций show или scene.

left

Выравнивает по левому нижнему углу экрана.

offscreenleft

Размещает отображаемый элемент за левой стороной экрана, с выравниванием по нижнему краю.

offscreenright

Размещает отображаемый элемент за правой стороной экрана, с выравниванием по нижнему краю.

reset

Сбрасывает трансформацию к значениям по умолчанию для каждого свойства, удаляя все свойства, установленные до этого.

right

Выравнивает по правому нижнему углу экрана.

top

Центрирует по горизонтали и выравнивает по верхнему краю экрана.

topleft

Выравнивает по левому верхнему углу экрана.

topright

Выравнивает по правому верхнему углу экрана.

truecenter

Центрирует как по горизонтали, так и по вертикали.

ATL - Язык анимации и трансформации

Язык анимации и трансформации (ATL) — это высокоуровневый язык, который может создавать анимации, перемещать отображаемые элементы по экрану, задавать их положение, применять трансформации и многое другое. Эти параметры могут изменяться со временем и в ответ на события.

Объекты ATL-трансформации, которые создаются с помощью инструкции Инструкция Transform ниже, являются отображаемыми элементами и могут использоваться как таковые (хотя они будут прозрачными, если их дочерний отображаемый элемент не установлен): их можно передать в элемент Add экрана, или в инструкцию Show с выражением (show expression), или в функцию renpy.show().

Инструкции скрипта Ren'Py

Существуют три инструкции скрипта Ren'Py, которые могут содержать ATL-код.

Инструкция Transform

Инструкция transform создает новую трансформацию, которую вы можете использовать для анимации и позиционирования отображаемых элементов в вашей игре. Трансформация является многоразовой и может применяться к изображениям и другим отображаемым элементам на протяжении всей игры с помощью предложения at в инструкциях show и scene.

Трансформации также могут действовать как отображаемые элементы и отображаться напрямую. Однако, в отличие от других отображаемых элементов, которые существуют в глобальном пространстве имен изображений (см. Определение изображений), трансформации создаются как переменные в соответствующем именованном хранилище (или в хранилище по умолчанию).

Трансформация создается во время init-фазы (при запуске игры).

Синтаксис

Основная форма:

transform <transform_name>:
    <atl_block>

С параметрами:

transform <transform_name>( <parameters> ):
    <atl_block>

Использование

Имя

Тип

Описание

transform_name

word

Имя трансформации.

Должно быть валидным идентификатором Python, разделенным точками

(например, my_transform или sprites.bounce)

parameters

--

(Необязательно) Параметры трансформации

atl_block

block

Блок ATL-кода, определяющий трансформацию

Вы можете добавлять параметры, чтобы сделать ваши трансформации гибкими и многоразовыми. Параметры работают аналогично параметрам функций в Python.

В настоящее время не поддерживается:

  • Только позиционные параметры (с использованием /)

  • Обязательные только именованные параметры (после * без значений по умолчанию)

  • *args (произвольное количество позиционных параметров)

  • **kwargs (произвольное количество именованных параметров)

Примечание

Пример

transform left_to_right:
    xalign 0.
    linear 2 xalign 1.
    repeat

transform ariana.left:
    xalign .3

transform animated_ariana_disp(duration=1.0):
    "ariana"
    pause duration
    "ariana_reverse"
    pause duration
    repeat

label start:
    show eileen happy at left_to_right
    pause
    show animated_ariana_disp
    pause

Инструкция Image с блоком ATL

Второй способ включения ATL-кода в скрипт — это использование его в составе инструкции image. Как и её встроенный аналог, она связывает имя изображения (которое может содержать пробелы) с данной трансформацией. Поскольку нет способа передать параметры, это полезно только в том случае, если трансформация определяет анимацию.

Синтаксис

image <image_name>:
    <atl_block>

Использование

Имя

Тип

Описание

image_name

word(s)

Имя изображения

atl_block

block

Блок ATL-кода, определяющий трансформацию

Пример

image animated_ariana_img:
    "ariana"
    pause 1.
    "ariana_reverse"
    pause 1.
    repeat

Инструкции Scene и Show с блоком ATL

Последний способ использования ATL — в составе инструкций show или scene. Это оборачивает отображаемое изображение в ATL-трансформацию, которая создается на лету и применяется к изображению.

Синтаксис

show <image_name>:
    <atl_block>

scene <image_name>:
    <atl_block>

Использование

Имя

Тип

Описание

image_name

word(s)

Имя изображения

atl_block

block

Блок ATL-кода, определяющий трансформацию

Пример

show eileen happy:
    xalign 1.

scene bg washington:
    zoom 2.

Синтаксис и инструкции ATL

Инструкции ATL могут быть встроенными или составлять блок внутри ATL-блока, в котором они написаны. За некоторыми исключениями, описанными в соответствующих инструкциях, инструкции в блоке ATL выполняются по порядку, сверху вниз.

Если инструкция ATL требует вычисления выражения, такое вычисление происходит при первом выполнении трансформации (то есть при использовании инструкции show или отображении трансформации как части экрана), а не при выполнении конкретной инструкции ATL.

Ниже перечислены инструкции ATL.

Инструкция Properties (свойства)

Эта инструкция устанавливает значение свойства трансформации.

Синтаксис

<property_name> <property_value>

Использование

Имя

Тип

Описание

property_name

word

Имя свойства трансформации (например, xalign, alpha, ...)

property_value

Varies

Значение свойства

Инструкция сначала указывает последовательность (не менее одного) имён свойств, каждое из которых сопровождается новым значением. Список свойств трансформации, их значение и принимаемые ими значения см. в Список свойств трансформации.

Пример

transform rightoid:
    xalign .9

transform ariana.left:
    xanchor .3 xpos 100

Числовая инструкция

Эта инструкция приостанавливает выполнение ATL-блока на указанную продолжительность. Ключевое слово "pause" является необязательным.

Синтаксис

pause <duration>

Использование

Имя

Тип

Описание

"pause"

keyword

(Необязательно) Ключевое слово, указывающее на паузу

duration

float, int (expr)

Время паузы в секундах

Примеры

transform pause_example(duration=0.5):
    xalign 0.0

    # Пауза на 2.0 секунды.
    pause 2.0
    xalign 1.0

    # Пауза на `duration` секунд.
    pause duration
    xalign 0.5

    # Пауза на 3.0 секунды.
    3.0

    repeat

Инструкция Interpolation (интерполяция)

Инструкция интерполяции — это основной способ получения плавно анимированных трансформаций. Значения изменяются со временем от их начального значения до заданного.

Для управления ходом интерполяции используется функция-варпер.

Синтаксис

Основная форма:

<warper_name> <duration> <atl_property> [<atl_property> ...]

С использованием функции-варпера:

warp <warper_function> <duration> <atl_property> [<atl_property> ...]

Форма с блоком:

<warper_name> <duration>:
    <atl_property>
    <atl_property>
    ...

Использование

Имя

Тип

Описание

warper_name

word

Имя встроенного варпера

warper_function

str, function (expr)

Функция-варпер с сигнатурой (t: float) -> float

duration

float, int (expr)

Время интерполяции в секундах

atl_property

Инструкция Properties (свойства)

Свойство для интерполяции

Интерполяция будет длиться указанное время, и как минимум один кадр.

Когда заданы Свойства трансформации, значение, которое им присваивается, — это значение, которое они примут в конце выполнения инструкции интерполяции.

Также можно интерполировать Инструкция выражения трансформа, который в этом случае должен быть ATL-трансформацией, содержащей только одну инструкцию свойств. Свойства из этой трансформации будут обрабатываться так, как если бы они были написаны непосредственно в этой интерполяции.

Примеры

Основное использование:

show logo base:
    xalign 0.0 yalign 0.0

    # За 2.0 секунды переместить объект в левый нижний угол.
    linear 2.0 yalign 1.0

С использованием функции-варпера:

show logo base(warper_expr="easein"):
    xalign 0.0 yalign 0.0

    # Используем варпер из параметра для перемещения в правую часть экрана.
    warp warper_expr 1.0 xalign 1.0

Несколько свойств:

show logo base:
    xalign 0.0 yalign 0.0

    # Одновременное изменение xalign и yalign.
    linear 2.0 xalign 0.5 yalign 0.5

    # То же самое, с использованием блока.
    linear 2.0:
        xalign 0.5
        yalign 0.5

Пользовательский варпер:

init python:
    def my_warper(t):
        return t**4.4

    my_warpers = [my_warper]

transform custom_warper_example:
    xpos 0
    warp my_warper 3 xpos 100
    warp my_warpers[0] 5 xpos 520

Интерполяция свойств

Сплайновое движение (по кривой траектории):

<atl_property> knot <knot_value> [knot <knot_value> ...]

Имя

Тип

Описание

knot_value

Varies (expr)

Значение контрольной точки свойства

Начальная точка — это значение свойства в начале интерполяции, конечная точка — это значение, указанное в <atl_property>. Узлы (knots) используются для управления сплайном.

Для одного узла используется квадратичная кривая Безье, для двух — кубическая кривая Безье, а для трех и более — сплайн Катмулла-Рома. В первых двух случаях узел или узлы являются просто контрольными точками. Для сплайна Катмулла-Рома первый и последний узлы — это контрольные точки (часто находящиеся за пределами видимой траектории), а остальные узлы — это точки, через которые проходит траектория.

transform spline_motion_single_property:
    # Начинаем в правом нижнем углу, немного уменьшив масштаб.
    zoom 0.5 xalign 1.0 yalign 1.0

    # Перемещаемся к центру внизу, немного пролетая дальше. Квадратичная кривая Безье.
    linear 2.0 xalign 0.5 knot 0.0

    # Перемещаемся вверх, замедляясь в центре. Кубическая кривая Безье.
    linear 2.0 yalign 0.0 knot 0.2 knot 0.8

    # Перемещаемся влево, сначала качнувшись. Сплайн Катмулла-Рома.
    linear 2.0 xalign 0.0 knot 1.0 knot 0.5 knot 0.0

transform spline_motion_multi_property:
    # Начинаем в правом нижнем углу, немного уменьшив масштаб.
    zoom 0.5 align (1.0, 0.0)

    # Используем сплайновое движение для одновременного перемещения (x, y) по небольшой S-образной кривой.
    linear 2.0 align (0.5, 1.0) knot (0.0, .33) knot (1.0, .66)

С круговым движением

<atl_property> clockwise
<atl_property> counterclockwise
<atl_property> circles <number_of_circles>

Имя

Тип

Описание

number_of_circles

int (expr)

Количество полных оборотов для кругового движения

Сравниваются начальное и конечное положения (которые устанавливаются с помощью pos, align, angle, radius и т.д.), и определяется центр полярных координат (который задается через around). Затем Ren'Py вычислит, на сколько градусов нужно повернуться, чтобы перейти от начального угла к конечному в указанном направлении вращения. Если указано предложение circles, Ren'Py гарантирует, что будет сделано соответствующее количество оборотов.

show logo base:
    xalign 1.0 yalign 0.0

    # Устанавливаем точку, вокруг которой будет происходить вращение.
    anchor (0.5, 0.5)

    # Используем круговое движение, чтобы развернуться по спирали к верхней части
    # экрана. На это потребуется 2 секунды.
    linear 2.0 yalign 0.0 clockwise circles 3

С выражением трансформации

<transform_expression>

Имя

Тип

Описание

transform_expression

Transform (expr)

Трансформация, к которой будет производиться интерполяция

В этом случае должна быть ATL-трансформация, содержащая только одну инструкцию свойств. Свойства из этой трансформации будут обрабатываться так, как если бы они были написаны непосредственно в этой интерполяции.

show logo base:
    xalign 1.0 yalign 0.0

    # Перемещаемся в позицию, указанную в трансформации truecenter, за 1.0 секунду
    ease 1.0 truecenter

Инструкция Pass

Инструкция pass ничего не делает: это пустая операция.

Синтаксис

pass

Ее можно использовать, когда нужно разделить инструкции, например, когда два набора инструкций choice (см. ниже) идут друг за другом. Также это может быть полезно, когда синтаксис требует создания блока, но он должен быть пустым, например, чтобы один из блоков choice ничего не делал.

Инструкция Repeat

Инструкция repeat заставляет блок, содержащий её, возобновить выполнение с начала.

Синтаксис

Основная форма:

repeat

С параметром count:

repeat <count>

Использование

Имя

Тип

Описание

count

int (expr)

(Необязательно) Количество выполнений блока

Блок, заканчивающийся на repeat 2, будет выполнен в общей сложности не более двух раз, а repeat 1 не вызывает повторений.

Инструкция repeat должна быть последней в блоке.

Пример

show logo base:
    xalign 0.0
    linear 1.0 xalign 1.0
    linear 1.0 xalign 0.0
    repeat

Инструкция Block

Инструкция block просто содержит блок ATL-инструкций. Это можно использовать для группировки инструкций, которые будут повторяться.

Синтаксис

block:
    <atl_block>

Пример

show 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

Инструкция parallel определяет набор ATL-блоков для параллельного выполнения.

Синтаксис

parallel:
    <atl_block>

Использование

Имя

Тип

Описание

"parallel"

keyword

Один или несколько параллельных блоков

atl_block

block

ATL-блок для этой параллельной ветки

Когда вы используете несколько параллельных блоков, они все выполняются одновременно. Инструкция parallel завершается, когда завершается последний блок.

Каждый параллельный блок должен быть независимым и изменять разные свойства трансформации. Например, один блок может управлять горизонтальным движением (xalign), а другой — вертикальным (yalign). Если два блока пытаются изменить одно и то же свойство одновременно, поведение непредсказуемо и этого следует избегать.

Параллельные инструкции жадно группируются в параллельный набор, когда более чем один параллельный блок появляется последовательно в блоке.

Пример

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

Инструкция choice определяет один из набора потенциальных вариантов. Ren'Py выберет один из вариантов в наборе и выполнит связанный с ним ATL-блок, а затем продолжит выполнение после последнего варианта в наборе.

Синтаксис

Основная форма:

choice:
    <atl_block>

С весом:

choice <weight>:
    <atl_block>

Использование

Имя

Тип

Описание

"choice"

keyword

Один или несколько вариантов

weight

float (expr)

(Необязательно) Вес этого варианта, по умолчанию 1.0

atl_block

block

ATL-блок для этого варианта

Инструкции choice жадно группируются в набор выбора, когда несколько инструкций choice появляются последовательно в блоке. Если предоставлено simple_expression, это вес с плавающей точкой, присваиваемый этому блоку, в противном случае предполагается 1.0.

Инструкция pass может быть полезна для разделения нескольких наборов блоков choice на несколько инструкций choice или для создания пустого блока choice.

Пример

image eileen random:
    choice:
        "eileen happy"
    choice:
        "eileen vhappy"
    choice 2.0:
        # Более вероятен для выбора.
        "eileen concerned"

    pause 1.0
    repeat

Инструкция Animation

Инструкция animation должна быть первой инструкцией в ATL-блоке и сообщает Ren'Py, что блок использует временную базу анимации (at), а не обычную временную базу показа (st). Для получения дополнительной информации см. Временные базы.

Синтаксис

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

Этот пример заставит Эйлин сменить выражение лица после первой паузы, но не изменит ее положение, так как обе анимации используют одно и то же время анимации и, следовательно, разместят ее спрайт в одном и том же месте. Без инструкции animation позиция сбрасывалась бы при клике игрока.

Инструкция On

Инструкция on определяет обработчик событий.

Синтаксис

Для одного события:

on <event_name>:
    <atl_block>

Для нескольких событий:

on <event_name>, <event_name>, ...:
    <atl_block>

Использование

Имя

Тип

Описание

event_name

word

Имя одного или нескольких событий для обработки

atl_block

block

ATL-блок для выполнения при наступлении события

Блоки on жадно группируются в одну инструкцию. Инструкция on может обрабатывать одно имя события или список имен событий, разделенных запятыми.

Эта инструкция используется для обработки событий. Когда событие обрабатывается, обработка любого другого события прекращается, и немедленно начинается обработка нового события. Когда обработчик события завершается без возникновения другого события, создается событие default (если событие default еще не обрабатывается).

Выполнение инструкции on никогда не завершается естественным образом. (Но оно может быть завершено инструкцией time или внешним обработчиком событий.)

Пример

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

Инструкция отображаемого элемента

Инструкция отображаемого элемента устанавливает или заменяет дочерний отображаемый элемент трансформа, когда инструкция выполняется. Вы также можете дополнительно добавить эффект перехода при смене одного отображаемого элемента на другой.

Синтаксис

Основная форма:

<displayable>

С переходом:

<displayable> with <transition>

Использование

Имя

Тип

Описание

displayable

Displayable (expr)

Новое дочернее изображение или визуальный элемент для отображения

transition

Transition (expr)

(Необязательно) Переход при смене отображаемых элементов

(например, dissolve, fade)

Примечание

Не все переходы работают в этом контексте. В частности, Словарные переходы, и переходы move и ease здесь не будут работать.

Использование трансформов как отображаемых элементов: Если вы передаёте другой ATL-трансформ, у которого уже есть дочерний отображаемый элемент, ваш текущий ATL-блок приостановится и будет ждать завершения анимации этого включённого трансформа перед тем, как продолжить.

Предупреждение

Если вы передадите трансформ без дочернего элемента, он станет прозрачным и ничего не будет отображать. ATL-трансформы без дочернего элемента могут быть интерпретированы как инструкция выражения трансформа, что приведёт к другим результатам.

Для новичков: Всегда убеждайтесь, что ваш отображаемый элемент является чем-то видимым, например, именем файла изображения ("logo.png") или отображаемым элементом с содержимым.

Пример

image atl example:
    "logo_base.png"

    pause 1.0

    "logo_bw.png" with Dissolve(0.5, alpha=True)

Инструкция выражения трансформа

Эта инструкция включает другой ATL-трансформ как часть текущего ATL-блока.

Синтаксис

<transform_expression>

Использование

Имя

Тип

Описание

transform_expression

Transform (expr)

Трансформ для интерполяции

Это применимо только в том случае, если ATL-трансформу не был предоставлен дочерний элемент (о том, как это сделать, см. в начале страницы), в противном случае инструкция будет интерпретирована как инструкция отображаемого элемента. Содержимое предоставленного ATL-трансформа включается в месте расположения этой инструкции.

Пример

transform move_right:
    linear 1.0 xalign 1.0

image atl example:
    # Display logo_base.png
    "logo_base.png"

    # Run the move_right transform.
    move_right

Встроенная инструкция contains

Эта инструкция устанавливает (или заменяет) дочерний элемент текущего ATL-трансформа на значение выражения, что делает её полезной для анимации.

Синтаксис

contains <displayable>

Использование

Имя

Тип

Описание

displayable

Displayable, Transform (expr)

Дочерний отображаемый элемент или трансформ

Инструкция отображаемого элемента менее явная и создаёт неоднозначность с инструкцией выражения трансформа, но она позволяет использовать переход при замене дочернего элемента. Эта инструкция может быть особенно полезна, когда ATL-трансформ должен содержать, а не включать в себя, второй ATL-трансформ.

Примечание

Используйте эту инструкцию, когда хотите, чтобы ваш ATL-трансформ содержал другой ATL-трансформ в качестве своего дочернего элемента. Это особенно полезно, когда вам нужно, чтобы дочерний элемент был отдельным объектом-трансформом, а не просто прямым включением его кода.

В противном случае, инструкция отображаемого элемента является более простым способом установить дочерний элемент, и у неё есть преимущество указания перехода, который воспроизводится при замене старого дочернего элемента на новый.

Пример

transform an_animation:
    "1.png"
    pause 2
    "2.png"
    pause 2
    repeat

image move_an_animation:
    contains an_animation

    # If we didn't use contains, we'd still be looping
    # and would never reach here.
    xalign 0.0
    linear 1.0 yalign 1.0

Блочная инструкция contains

Блок contains, как и его встроенный аналог, устанавливает дочерний элемент трансформа, но делает это по-другому.

Синтаксис

contains:
    <atl_block>

Использование

Один или несколько блоков contains будут жадно сгруппированы в одну инструкцию contains, обёрнуты в Fixed() и установлены в качестве дочернего элемента трансформа.

Каждый блок должен определять отображаемый элемент для использования, иначе произойдёт ошибка. Инструкция 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

Инструкция function позволяет использовать код Python внутри ATL.

Синтаксис

function <func>

Использование

Имя

Тип

Описание

func

function (expr)

Функция для вызова, с сигнатурой (trans: Transform, st: float, at: float) -> float | None

Функции имеют ту же сигнатуру, что и те, которые используются с Transform():

  • Первый аргумент — это объект-трансформ. Свойства трансформа можно устанавливать как атрибуты этого объекта.

  • Второй аргумент — это временная база показа (timebase), количество секунд с момента начала выполнения функции.

  • Третий аргумент — это временная база анимации, то есть количество секунд, в течение которых что-то с тем же тегом находится на экране.

  • Если функция возвращает число, она будет вызвана снова по истечении этого количества секунд. (0 секунд означает вызов функции как можно скорее.) Если функция возвращает None, управление перейдёт к следующей инструкции ATL.

Эта функция не должна иметь побочных эффектов, кроме изменения объекта-трансформа в первом аргументе, и может быть вызвана в любое время с любым значением в рамках предсказания.

Обратите внимание, что function не является свойством трансформа, и её поведение не полностью совпадает с поведением параметра function у Transform().

Пример

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

Инструкция time является управляющей инструкцией.

Синтаксис

time <value>

Использование

Имя

Тип

Описание

value

float/int (expr)

Время в секундах от начала выполнения блока

Когда достигается значение, указанное в инструкции, начинает выполняться следующая инструкция. Эта передача управления происходит, даже если предыдущая инструкция всё ещё выполняется, и заставляет любую такую предыдущую инструкцию немедленно завершиться.

Если инструкция time достигается до заданного значения времени, трансформ приостанавливается и ждёт, пока инструкция time не возьмёт управление.

Если в блоке несколько инструкций time, их значения времени должны строго возрастать.

Пример

image backgrounds:
    "bg band"
    xoffset 0
    block:
        linear 1 xoffset 10
        linear 1 xoffset 0
        repeat # control would never exit this block

    time 2.0
    xoffset 0
    "bg whitehouse"

    time 4.0
    "bg washington"

Инструкция event

Инструкция event вызывает генерацию события с указанным именем.

Синтаксис

event <event_name>

Использование

Имя

Тип

Описание

event_name

word

Имя события для генерации

Когда событие генерируется внутри блока, блок проверяется на наличие обработчика событий для данного имени. Если он существует, управление передаётся этому обработчику. В противном случае событие распространяется на любой содержащий его обработчик событий.

Внешние события

Следующие события срабатывают автоматически внутри ATL-трансформа:

start

Псевдо-событие, срабатывает при входе в инструкцию on, если не произошло событие с более высоким приоритетом.

show

Срабатывает, когда трансформ отображается с помощью инструкции show или scene, и изображение с указанным тегом не существует.

replace

Срабатывает, когда трансформ отображается с помощью инструкции show, заменяя изображение с указанным тегом.

hide

Срабатывает, когда трансформ скрывается с помощью инструкции hide или её эквивалента в Python.

Обратите внимание, что это событие не срабатывает, когда трансформ удаляется с помощью инструкции scene или при выходе из контекста, в котором он существует, например, при выходе из игрового меню.

replaced

Срабатывает, когда трансформ заменяется другим. Изображение фактически не скроется до тех пор, пока ATL-блок не завершит свою работу.

hover, idle, selected_hover, selected_idle, insensitive, selected_insensitive

Срабатывает, когда кнопка, содержащая этот трансформ, или кнопка, содержащаяся в этом трансформе, переходит в указанное состояние.

Каррирование и частичная передача параметров в ATL

Параметры ATL-трансформа, определённого с помощью инструкции transform, можно задавать в разное время. При вызове ATL-трансформа как функции результирующее значение по-прежнему является трансформом, а параметры, которым было передано значение, рассматриваются так, как будто это значение является новым значением по умолчанию для параметра.

Например:

transform screamer(child, screamee, wait_time=2, flash_time=.1):
    child
    pause wait_time
    screamee
    pause flash_time
    child

# doing this doesn't raise an error (it would if it were a Python function)
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)
    "Here is one way"

    show eileen vhappy at eileen_excited_screamer
    "Here is another"

    show patricia sad at eileen_excited_screamer(screamee="patricia wow")
    "And you can also do this"

Обратите внимание, что трансформ shorter_screamer, так же как и screamer, не может быть использован напрямую, как show eileen at screamer, поскольку их параметрам screamee не было присвоено значение.

Также обратите внимание, что, подобно меткам и экранам, значения по умолчанию для параметров трансформа, созданного непосредственно инструкцией transform, будут вычислены в момент, когда трансформ вызывается, а не в момент, когда он определяется.

Однако, у трансформа, полученного в результате вызова другого трансформа (например, shorter_screamer в примере выше, или также трансформ, применённый к patricia), все значения параметров по умолчанию уже вычислены. Это относится как к значениям, полученным из вычисления значений по умолчанию в исходном трансформе (например, параметр flash_time у shorter_screamer или wait_time у трансформа для patricia), так и к значениям, переданным ему при вызове ранее в строке (например, параметр wait_time у shorter_screamer или параметры screamee и flash_time у трансформа для patricia).

Специальный параметр Child

Если у ATL-трансформа есть параметр с именем «child» и этот параметр получает значение, независимо от типа параметра или способа, которым он получает значение (позиционный аргумент или по ключевому слову, и даже если параметр является только позиционным или только ключевым, и с значением по умолчанию или обязательным), то параллельно дочерний элемент трансформа устанавливается равным значению этого параметра.

Обратите внимание, что значение параметра по умолчанию не учитывается; параметр должен получить значение извне.

И наоборот, когда этот ATL-трансформ используется как трансформ, будет передан именованный аргумент child=, и поэтому, в дополнение к установке дочернего элемента, если есть параметр для его приёма (исключая позиционные параметры, так как он передаётся по ключевому слову), он получит значение дочернего элемента при выполнении трансформа.

Например, это позволяет переключаться между предоставленным дочерним элементом и другим отображаемым элементом:

transform lucy_jump_scare(child):
    # the child is implicitly set as the child of the transform
    pause 5

    # Jump scare
    "lucy mad"
    pause .2

    # Go back to the original child
    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-переходов.

Варперы

Варпер (warper) — это функция, которая может изменять количество времени, которое, по мнению инструкции интерполяции, прошло. Они определяются как функции от t до t', где t и t' — числа с плавающей запятой, при этом t изменяется от 0.0 до 1.0 в течение заданного промежутка времени. (Если продолжительность инструкции равна 0, то при её выполнении t равно 1.0.) t' должен начинаться с 0.0 и заканчиваться на 1.0, но может быть больше или меньше. По умолчанию определены следующие варперы.

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)

Кроме того, поддерживается большинство функций сглаживания Роберта Пеннера. Чтобы имена соответствовали приведённым выше, функции были немного переименованы. Графики этих стандартных функций можно найти на https://easings.net/.

Ren'Py Name

easings.net Name

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, доступный только для чтения, который содержит перечисленные выше функции. Это полезно для элементов Ren'Py, которые принимают функцию искажения времени, например, Dissolve(), который можно использовать так:

with Dissolve(1, time_warp=_warper.easein_quad)

Новые варперы можно определить с помощью декоратора renpy.atl_warper в блоке python early. Он должен быть размещён в файле, который анализируется до любого файла, использующего этот варпер. Это выглядит так:

python early hide:

    @renpy.atl_warper
    def linear(t):
        return t

Замена трансформов

Когда ATL-трансформ, встроенный трансформ или трансформ, определённый с помощью класса Transform, заменяется другим трансформом из этих же категорий, свойства уходящего трансформа наследуются входящим трансформом. Это наследование не применяется для других видов трансформов.

Когда инструкция show имеет несколько трансформов в списке at, трансформы сопоставляются с конца к началу, пока один из списков не закончится. Например:

show eileen happy at a, b, c
"Dialogue !"
show eileen happy at d, e

Трансформ c будет заменён на e, трансформ b будет заменён на d, а трансформ 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

В этом примере изображение будет отскакивать слева направо и обратно, пока игрок не кликнет. Когда это произойдёт, свойство xalign трансформа bounce будет использовано для инициализации свойства xalign трансформа headright, и таким образом изображение начнёт двигаться с того места, где оно находилось в момент клика.

Свойства положения (xpos, ypos, xanchor, yanchor и свойства, их устанавливающие, такие как xalign или radius/ angle) имеют особое правило наследования: значение, установленное в дочернем элементе, переопределит значение, установленное в родительском. Это связано с тем, что отображаемый элемент может иметь только одно положение, и активно установленное положение имеет приоритет.

Наконец, когда инструкция 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."

Временные базы

Существуют две временные базы, которые часто путают:

  • st (shown timebase, временная база показа): начинается, когда этот отображаемый элемент впервые появляется на экране.

  • at (animation timebase, временная база анимации): начинается, когда было показано изображение с тем же тегом, и с тех пор оно не скрывалось.

Когда отображаемый элемент показывается без тега, st и at совпадают.

Примечание

По умолчанию трансформы используют st. Используйте animation, чтобы переключиться на at.

Класс Transform

Одним из эквивалентов простейших ATL-трансформов является класс Transform.

class Transform(child=None, *, function=None, reset=False, **properties)

Создаёт трансформ, который применяет к своему дочернему элементу такие операции, как обрезка, вращение, масштабирование или альфа-смешение. Объект-трансформ имеет поля, соответствующие свойствам трансформа, которые он применяет к своему дочернему элементу.

child

Дочерний элемент, к которому применяется трансформ.

reset

Если True, трансформ сбросит свойства до их значений по умолчанию при показе, вместо того чтобы наследовать эти свойства от заменяемых им трансформов.

function(trans: Transform, st: float, at: float, /) → float | None

Если не None, эта функция будет вызываться при рендеринге трансформа с тремя позиционными аргументами:

  • Объект-трансформ.

  • Временная база показа, в секундах.

  • Временная база анимации, в секундах.

Функция должна возвращать задержку в секундах, по истечении которой она будет вызвана снова, или None, чтобы быть вызванной снова в начале следующей интеракции.

Эта функция не должна иметь побочных эффектов, кроме изменения объекта Transform в первом аргументе, и может быть вызвана в любое время с любым значением в рамках предсказания.

Дополнительные именованные аргументы — это значения, которым присваиваются свойства трансформа. Эти конкретные свойства трансформа будут устанавливаться каждый раз при отрисовке трансформа, и поэтому их нельзя будет изменить после создания объекта Transform. Однако поля, соответствующие другим свойствам трансформа, можно устанавливать и изменять позже, либо внутри функции, переданной как параметр function, либо непосредственно перед вызовом метода update().

hide_request

Этот атрибут устанавливается в true, когда вызывается функция, чтобы указать, что трансформ скрывается.

hide_response

Если hide_request равен true, этот атрибут можно установить в false, чтобы предотвратить скрытие трансформа.

original_child

Это дочерний Displayable, который был установлен при создании трансформа, до любых вызовов set_child. Может быть None, если дочерний элемент не был установлен при создании.

set_child(child)

Вызовите этот метод с новым child, чтобы изменить дочерний элемент этого трансформа.

update()

Этот метод следует вызывать, когда поле свойства трансформа обновляется вне функции, переданной в качестве аргумента function, чтобы убедиться, что изменение вступило в силу.

unique():

Этот метод следует вызывать для только что созданного трансформа, чтобы пометить его как уникальный. Обычно трансформы копируются при добавлении к отображаемому элементу, сбрасывая состояние трансформа. Вызов этого метода предотвращает такое поведение и полезен, когда вы хотите создать трансформ, который сохраняет состояние между несколькими использованиями, или к которому необходимо обращаться извне его аргумента function.

Эта функция возвращает Transform.

Применение трансформов к отображаемым элементам в Python

Существует несколько способов применить трансформ t к отображаемому элементу d в Python:

  1. Самый универсальный и рекомендуемый способ — это At(d, t) (см. ниже). Он работает со всеми трансформами.

  2. d(child=t) работает со всеми ATL-трансформами.

  3. t(d) работает со всеми трансформами на Python, а также с ATL-трансформами, у которых нет позиционных параметров.

At(d, *args)

Для заданного displayable d применяет к нему каждую из трансформаций в args. Трансформации применяются в порядке слева направо, так что самая внешняя трансформация — это самый правый аргумент.

transform birds_transform:
    xpos -200
    linear 10 xpos 800
    pause 20
    repeat

image birds = At("birds.png", birds_transform)

Примечание

Результирующее значение может не отображаться, если у трансформа остались параметры, которым не было присвоено значение, как это может быть в случае с трансформами, определёнными с помощью инструкции transform.

Примечание

Результирующее значение всё ещё может быть трансформом, который можно применить к другому отображаемому элементу (переопределяя его предыдущий дочерний элемент); так обстоит дело с ATL-трансформами, которые по-прежнему можно использовать как трансформы даже после установки их дочернего элемента.

Вызываемые объекты как трансформы

Наконец, простые вызываемые объекты Python можно использовать в качестве трансформов. Эти вызываемые объекты должны принимать один отображаемый элемент в качестве аргумента и возвращать новый Displayable. Например:

init python:

    # this transform uses the right and left transforms
    def right_or_left(d):
        if switch:
            return At(d, right)
        else:
            return At(d, left)

Это означает, что некоторые встроенные функции, которые принимают отображаемый элемент и возвращают отображаемый элемент, такие как Flatten(), также являются трансформами и могут использоваться в этом качестве.