воскресенье, 8 июля 2012 г.

Ren'Py - анимация и трансформация (ATL)


Animation and Transformation Language




Функции Анимации и Трансформации (преобразования) обеспечивают множество вариантов отображения объектов, расположения их на экране, а также применение к ним таких

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


(Вот так обозначается текст который я не допер как перевести при.переводчика)


В языке программирования Python, эквивалент ATL-трансформации - функция Transform(). Не существует способа программно создать ATL-трансформирование.


Основные Операторы Сценария Ren’Py


ATL-код включает в себя три основных оператора сценария.

Оператор Преобразования

Оператор Преобразования создает трансформацию, которая может являться частью другого сценария. Синтаксис Преобразования:

atl_transform ::=  "transform" имя "(" параметры ")" ":"
                     
atl-блок кода

Преобразование (трансформация) должно быть запущено в определенное время. Если оператор находится за пределами блока инициализации, то автоматически помещается в блок с приоритетом 0. Преобразование может иметь список параметров, которые должны быть указаны во время его вызова.

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

transform left_to_right:
   
xalign 0.0
   
linear 2.0 yalign 1.0
   
repeat

show eileen at left_to_right


Оператор изображения с ATL-кодом

Вторым способом использования ATL является оператор изображения с ATL-кодом. Он создает связь имени изображения с преобразованием. В данном случае трансформации невозможно задать никаких параметров и изображение используется только как анимация. Синтаксис оператора:

atl_image ::=  "image" имя_изображения ":"
                 
atl-блок кода

image eileen animated:
   
"eileen_happy.png"
   
pause 1.0
   
"eileen_vhappy.png"
   
pause 1.0
   
repeat

Операторы Scene и Show с ATL-кодом

Последним способом является использование ATL в функциях Scene и Show. ATL-преобразование изображения происходит внутри блока функции.

atl_scene ::=  stmt_scene ":"
                  
atl-блок кода
atl_show ::=  stmt_show ":"
                   
atl-блок кода

scene bg washington:
   
zoom 2.0
show eileen happy:
   
xalign 1.0


Синтаксис и Семантика ATL-кода

Блок ATL-кода состоит из одной или нескольких строк, все они располагаются с тем же отступом как и отступ относительно блока, в котором находится оператор. Каждая строка в блоке ATL-кода должна содержать один или несколько ATL-операторов.

Есть два вида ATL-операторов : “простые” и “сложные”. “Простые”  операторы обходятся без ATL-блока. Они располагаются в единую линию, могут содержать одно или несколько ATL-заявлений, разделенных запятыми. “Сложные” операторы содержат блок ATL-кода, каждый оператор которого располагается на отдельной строке. В первой строке “сложный” оператор всегда заканчивается двоеточием (:).

По умолчанию, операторы в ATL-блоке выполняются в том порядке, в каком они написаны, т.е. начиная с первого оператора блока. Выполнение завершается, когда достигается конец блока. Однако существуют операторы которые могут этот порядок изменить, но об этом чуть позже.
Блок заканчивает свое выполнение, когда все операторы в блоке были прекращены.
Если ATL-оператор требует вычисления какого-либо выражения, такое вычисление происходит когда преобразование впервые добавлено в список объявленных трансформаций (например, при использовании Show или UI функции).

ATL операторы

Ниже мы рассмотрим все операторы ATL языка.

Оператор Интерполирования

Оператор Интерполяции являются основным способом контролирования ATL-трансформаций. 

(Гугл мне не дал внятного ответа, но как я понял - Интерполяция, в нашем случае, это изменение положения объекта/картинки в пространстве. прим. переводчика)

atl_interp ::=  ( warper простое_выражение | "warp" простое_выражение простое_выражение )?
               (
property простое_выражение( "knot" простое_выражение )*
               | "clockwise"
               | "counterclockwise"
               | "circles" simple_expression
               | simple_expression )*

Первая часть оператора интерполяции используется для выбора функции изменения времени данной интерполяции (то есть выбор линейного(последовательного) течения времени или нет). Это можно сделать дав имя одному из существующих в ATL-языке варперу (см. ниже, раздел Варперы), или использовать ключевое слово “warp” перед выражением представляющим функцию. В обоих случаях это сопровождается числом, соответствующим количеству секунд, которое занимает выполнение этой интерполяции.

Если warp функция не задана, то интерполяция начинается с 0-ой секунды, используя функции pause (паузы).

Варппер и его продолжительность используются для расчета завершения интерполяции. Это делается путем деления необходимого на интерполяцию времени и ее реальной продолжительности. Полученное значение становиться продолжительностью. Результат возвращается к варпперу интерполяции и завершает ее.

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

  • Если значение представлено одним или двумя значениями, то вводиться сплайн (траектория) движения (хотя это и не относиться к Ren'Py или Puthon, понять что такое сплайн можно здесь. прим. переводчика). Отправной точкой сплайна является первое значение параметра на момент начала интерполяции, конечная точка вычисляется используя указанное для регулирования сплайна второе значение.
  • Если в операторе интерполяции используется способ “clockwise” или “counterclockwise”, в таком случае будет использоваться движение объекта по часовой и против часовой стрелки соответственно.
  • В противном случае используется линейный (движение по прямой) переход между указанными координатами начала и конца интерполяции.

Если представлено “простое” выражение, оно должно использоваться для преобразования только с одним оператором интерполяции без варпера, сплайна, или кругового движения. Свойства преобразования обрабатываются как если бы они были включены в оператор.
Несколько примеров интерполяции:

show logo base:
    
# Показать логотип в правом верхнем углу экрана.
    
xalign 0.0 yalign 1.0

    
# Переместить его обратно влево за одну секунду.
    
linear 1.0 xalign 0.0

    
# За 1 секунду переместить логотип в место используемое трансформатором
    # truecenter. Для этого используем варпер ease.
    
ease 1.0 truecenter

    
# Выдержим секундную паузу.
    
pause 1.0

    
# Укажем точку, которая будет являться центром вращения.
    
alignaround (.5, .5)

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

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

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

Некоторые свойства могут иметь значения разных типов. Например, xpos может быть целым (int), дробным (float), или абсолютным (absolute). Поведение интерполяции будет не определенным, когда ее старые и новые значения свойств будут различных типов.

Оператор Time

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

atl_time ::=  "time" simple_expression

Когда время указанное оператору будет достигнуто, свое выполнение начнет следующий оператор. Выполнение следующего оператора происходит, даже если предыдущие операторы по-прежнему выполняется и независимо от их приоритета они немедленно будут прекращены.
Оператору Time неявно предшествует оператор паузы (pause) с бесконечным временем выполнения. Это означает что если контроль не передан оператору time, то до тех пор пока он не возьмет этот контроль время будет остановлено.

При наличии нескольких операторов Time в одном блоке, они должны выполняться строго в заданном порядке.

image backgrounds:
   
"bg band"
   
time 2.0
   
"bg whitehouse"
   
time 4.0
   
"bg washington"


Операторы Выражений

Операторы Выражений это простые операторы начинающееся с простого_выражения. Затем объявляется дополнительный пункт с второй простым выражением.

atl_expression ::=   simple_expression ("with" simple_expression)?

Есть три варианта, к которым может привести первое простое_выражение:

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

image atl example:
    
# Показать logo_base.png
    
"logo_base.png"

    
# Поставить паузу на 1 секунду.
    
1.0

    
# Отобразить logo_bw.png с dissolve (растворением).
    
"logo_bw.png" with Dissolve(0.5, alpha=True)

    
# Запустить преобразование move_right (сдвинуть вправо).
    
move_right

Оператор Пропуска

atl_pass ::=  "pass"

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

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

atl_repeat ::=  "repeat" (simple_expression)?

Оператор Повтора должен быть последним операторо в блоке кода

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

Оператор Блок-кода

Оператор Блок-кода это “сложный” оператор содержащий блок ATL-кода. Он может использоваться для того чтобы сгруппировать другие операторы, которые будут повторяться.

atl_block_stmt ::=  "block" ":"
                        
atl_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


Оператор Выбора

Оператор Выбора является “сложным” оператором предоставляющим выбор одного варианта из множества потенциальны. Ren'Py выберет один (как я понял рандомом прим. переводчика) из вариантов в предоставленном наборе, выполнит блок ATL-кода связанный с ним, а затем продолжить выполнение кода после последнего выбор в наборе вариантов.

atl_choice ::=  "choice" (simple_expression)? ":"
                   
atl_block

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

image eileen random:
   
choice:
       
"eileen happy"
   
choice:
       
"eileen vhappy"
   
choice:
       
"eileen concerned"

   
pause 1.0
   
repeat

Оператор Параллельного Выполнения

Оператор Параллельного выполнения используется для одновременного выполнения 2-х и более блоков ATL-кода.

atl_parallel ::=  "parallel" ":"
                    
atl_block

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

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

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


Оператор Событий

Оператор Событий это простой оператор, вызывающий событие с заданным именем, для его выполнения.

atl_event ::=  "event" name

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

Оператор Включения

Оператор включения является “сложным” оператором включающим в себя обработчик событий.

atl_on ::=  "on" name ":"
                
atl_block

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

Выполнение оператора включения никогда не закончится самостоятельно (но оно может быть закончено оператором Time, или ограждающим обработчиком события).

show logo base:
   
on show:
       
alpha 0.0
       
linear .5 alpha 1.0
   
on hide:
       
linear .5 alpha 0.0

Оператор Содержания

Оператор содержания (contains) устанавливает отображаемое содержимое  в данной ATL-трансформации. Есть два варианта этого оператора.

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

atl_contains ::=  "contains" expression

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

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

atl_counts ::=  "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

Оператор Функций


Оператор Функций позволяет ATL использовать Python функции для управления ATL свойствами.

atl_function ::=  "function" expression

Функции имеют туже структуру как и при использовании  Transform():

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

init python:
   
def slide_function(trans, st, at):
       
if st > 1.0:
           
trans.xalign = 1.0
           
return None
       
else:
           
trans.xalign = st
           
return 0
label start:
   
show logo base:
       
function slide_function
       
pause 1.0
       
repeat

Warpers (Варперы)

Варпер это функция, которая может изменить количество времени приводящее интерполяцию к завершению. Данные варперы определены по умолчанию, они определяются в области от т до т’, где т и т’ числа с плавающей точкой, значения которых колеблются между 0.0 и 1.0. (если продолжительность оператора 0, тогда t=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)

Новые варперы можно создать с помощью конструктора renpy.atl_warper, в предшествующем Python блоке. Он должен находиться в файле, который обрабатывается до файла используемого варпером. Код выглядит следующим образом:

python early hide:

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


Список Трансформаторов Atl-кода

Существуют следующие трансформаторы.

Когда тип задается как положение на экране, это может быть целое число, renpy.absolute, или число с плавающей точкой. Если это число с плавающей точкой, оно интерпретируется как доля от размера содержащей его области (постфикс POS) или отображаемой области (постфикс ANCHOR).

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

pos
type: (позиция, позиция)
default: (0,0)

Положение по отношению к верхнему левому углу в содержащейся области.

xpos
type: позиция
default: 0

Горизонтальное положение по отношению к левой стороне в содержащейся области.

ypos
type: позиция
default: 0

Вертикальное положение относительно верхней части в содержащейся области.

anchor
type: (позиция, позиция)
default: (0,0)

Точка положения относительно верхнего левого угла отображаемой области.

xanchor
type: позиция
default: 0

Горизонтальное положение точки по отношению к левой стороне отображаемой области.

yanchor
type: позиция
default: 0

Вертикальное положение относительно верхней части отображаемой области.

align
type: (float, float)
default; (0.0, 0.0)

Эквивалентно установки pos и anchor с тем же значением.

xalign
type: float
default; 0.0

Эквивалентно установки xpos и xanchor к этому значению.
yalign
type: float
default; 0.0

Эквивалентно установки ypos и yanchor к этому значению.

xcenter
type: float
default: 0.0

Эквивалентно установке xpos значению этого варпера и xanchor 0.5

ycenter
type: float
default: 0.0

Эквивалентно установке ypos значению этого варпера и yanchor 0.5

rotate
type: float или None
default: None

Если значение None, то вращения не происходит. В других случаях изображение будет повернуто по часовой стрелке на указанное количество градусов. Поворот отображаемого объекта изменяет его размер в зависимости от настройки rotate_pad (см. ниже). Это может привести к изменению позиции, если xanchor и yanchor не 0,5.

rotate_pad
type: boolean
default: true

Если значение true, то поворачиваемый отображаемый объект обрабатывается таким образом чтобы ширина и высота равные гипотенузе были равны оригинальной ширине и высоте. Это гарантирует, что преобразование не изменит размер вращаемого объекта. Если значение False, преобразование будет оперировать минимальным размером отображаемого объекта. Это больше подходит для фиксированного вращения.

zoom
type: float
default: 1.0

Это приводит к увеличению отображаемого объекта в указанное количество раз. Это значение должно быть всегда больше чем 0,5.

xzoom
type: float
default: 1.0

Это приводит к горизонтальному увеличению отображаемого объекта в указанное количество раз. Это значение должно быть всегда больше чем 0,5.

yzoom
type: float
default: 1.0

Это приводит к вертикальному увеличению отображаемого объекта в указанное количество раз. Это значение должно быть всегда больше чем 0,5.

alpha
type:float
default:1.0

Настройки прозрачности отображаемого объекта

around
type:(позиция, позиция)
default: (0.0, 0.0)

Если значение не None, указывает полярные координаты центра, относительно верхнего левого угла содержащей области. Установка этого параметра позволяет совершать круговые движения вокруг указанной точки в режиме изменения позиции (pos).

alignaround
type: (float,float)
default: (0.0,0.0)

Если значение не None, указывает полярные координаты центра, относительно верхнего левого угла содержащей области. Установка этого параметра позволяет совершать круговые движения вокруг указанной точки в режиме изменения выравнивания (align).

angle
type:float

Получить угол объекта полярных координат позиции. Это значение не определено, когда полярные координаты центра не установлены.

radius
type: позиция

Получить радиус объекта полярных координат позиции. Это значение не определено, когда полярные координаты центра не установлены.

crop
type: None или (int,int,int,int)
default: None

Если значение не None, приводит к тому, что отображаемый объект должен быть обрезана в данной области. Область определяется как тюпль (х, у, ширина, высота).

corner1
type: None или (int,int)
default: None

Если значение не None, дает обрезанной области верхний левый угол. Оператор имеет приоритет над оператором crop.

corner2
type: None или (int,int)
default: None

Если значение не None, дает обрезанной области нижний правый угол. Оператор имеет приоритет над оператором crop.

size
type: None или (int,int)
default: None

Если значение не None, приводит к тому что отображаемый объект масштабируется до заданного размера.

subpixel
type: boolean
default: false

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

delay
type:float
default: 0.0

Если эта трансформация используется как переход, то это длительность перехода.

Эти свойства применяются в следующем порядке:

  1. crop, corner1, corner2
  2. size
  3. rotate
  4. zoom, xzoom, yzoom
  5. операторы изменения положения

Движение по кругу

Если оператор интерполяции содержит ключевые слова clockwise или counterclockwise, интерполяция будет вызвана с круговыми движениями. Ren'Py будет сравнивать начальное  и конечное местоположение и ​​выяснит полярные координаты центра. Затем Ren'Py вычислит количество градусов, которое потребуется для перехода от начального угла к конечному, в указанном направлении вращения. Если дается число кругов, Ren'Py гарантирует, что нужное количество кругов будет совершенно.
Ren'Py, при необходимости, затем интерполирует операторы угла и радиуса, для того чтобы произошло круговое движение. Если преобразование в режиме выравнивания, установки угла и радиуса установятся согласно выравниванию. В противном случае будет установлен оператор pos.

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

Следующие события могут быть вызваны автоматически:
start
Псевдо-событие, срабатывает в момент перехода к оператору, если нет события с более высоким приоритетом выполнения.
show
Срабатывает, когда выполняется трансформация используя операторы Show или Scene и не существует изображения с заданным тегом.
replace
Срабатывает, когда выполняется трансформация с использованием оператора Show, заменяя изображения с заданным тегом.
hide
Срабатывает, когда трансформация скрыта с помощью оператора скрытия языка Python или его эквивалента.
replaced
Срабатывает, когда трансформация сменяется другой. Изображение не будет на самом деле скрыто, пока блок ATL -кода завершается.
hover, idle, selected_hover, selected_idle
Срабатывает когда кнопка содержащая эту трансформацию или кнопка содержащаяся в этой трансформациипереходит в названное состояние (то есть когда на нее указывают курсором - hovered, не указывают курсором - idle, указывают / не указывают курсором на кнопку, которая отмечена как выбранная - selected_hover / selected_idle соответственно прим. Алекс__).

2 комментария:

  1. Спасибо! Полезная статья.

    ОтветитьУдалить
  2. по поводу choice немного по-сложнее. Если нет выражения, то выбор случаен. вместо выражения можно ставить float - он будет восприниматься, как приоритет. А можно явно указать условие, при котором будет сделан именно этот выбор. Вот пример:
    https://forums.tigsource.com/index.php?topic=19166.0

    ОтветитьУдалить