ATL (анимации и трансформации) - TrueCat17/Ren-Engine GitHub Wiki
ATL - это язык описания анимаций и трансформаций для спрайтов, показываемых командой show
.
Во многом он похож на ScreenLang.
Команды выполняются друг за другом.
Может быть использован в 3-х случаях:
- При объявлении изображения:
image np smile = "images/sprites/np/np_smile.png":
size (0.3, 1.0)
- При показе, используя параметр
at
:
show np smile at left
- При показе, используя синтаксис 1-го способа:
show np smile:
# По сути, это именно то, что и делает left после at
pos (0.28, 1.0)
anchor (0.5, 1.0)
Разумеется, никто не запрещает применить все эти способы одновременно к одному изображению.
Порядок выполнения - ровно тот, что показан выше.
Если 2 и 3 способ не используются, то на месте 2-го используется center
.
Если это нежелательно, можно указать None
в качестве at
-параметра: show np smile at None
Если не используется 1-й способ, то на его месте используется default_decl_at
.
Эта переменная - список строк-команд (по умолчанию пуст), пример использования (в init
-секции):
$ default_decl_at = ["size (1.0, 1.0)"]
# Все объявленные дальше изображения будут растянуты/сжаты так, чтобы занимать всё окно.
image bg some1 = "images/image.png"
image bg some2 = "images/other_image.jpg"
image bg some3 = "images/also_image.png"
# Здесь это надо добавить вручную, т. к. 1-й способ всё же используется.
image bg with_alpha = "images/some_image.png":
alpha 0.6
size (1.0, 1.0)
$ default_decl_at = []
# Возвращаем назад, чтобы объявленные дальше картинки не растягивались.
-
alpha
,rotate
-
xpos
,ypos
,pos
-
xanchor
,yanchor
,anchor
-
xalign
,yalign
,align
-
xsize
,ysize
,size
-
xzoom
,yzoom
,zoom
crop
Все эти свойства из ScreenLang доступны (+ есть xcrop
, ycrop
, xsizecrop
, ysizecrop
).
Хотя есть одно исключение: относительные размеры вложенных спрайтов
рассчитываются относительно размеров своих "родителей", а не относительно окна.
И всё так же можно (если вдруг сильно надо) написать их в одну строку:
show np smile:
pos (0.28, 1.0) anchor (0.5, 1.0)
Или в сокращённой форме:
show phone msg:
align 0.5 # как <align (0.5, 0.5)> или <xalign 0.5 yalign 0.5>
Точно так же, как и внутри label
: pause 1.5
Ну или просто 1.5
(команда считается за время паузы, если при её выполнении как python-кода в результате получается число: int
, float
или long
).
Если первым параметром в строке идёт функция, то считается, что сейчас идёт плавное изменение (тогда 2-м параметром считается время).
Например, так можно передвинуть изображение слева направо:
xalign 0.0
linear 1.5 xalign 1.0
Кроме linear
(равномерно) есть ещё ease
(ускорение в начале, замедление в конце), easein
(в начале быстро, в конце медленно) и easeout
(в начале медленно, в конце быстро).
Можно использовать и свою функцию: она должна принимать число от 0 (начало анимации) до 1 (конец) и выдавать число от 0 (начальные координаты) до 1 (конечные).
Например:
-
linear
выдаёт то же самое, что и получает (отсюда и линейность), -
ease
ведёт себя по другому:return 0.5 - math.cos(math.pi * t) / 2.0
.
Если поставить команды друг за другом, то они будут выполняться по очереди, но это может быть нежелательно (например, если используются плавные изменения). Тогда можно сделать так:
parallel:
xalign 0.0
linear 1 xalign 1.0
linear 1 xalign 0.0
repeat
parallel:
yalign 1.0
linear 3 yalign 0.0
linear 3 yalign 1.0
repeat
Исполнение parallel
считается завершённым, если все parallel
-блоки были завершёны.
Как можно было увидеть в предыдущем примере, можно вернуться к первой команде текущего блока, использовав repeat
.
Если после этого указать число (repeat 3
, например), то это будет считаться за количество повторов.
После указанного количества будет произведён переход на команду после этого repeat
(если там дальше что-то есть),
а количество повторов во всех предыдущих repeat
будет обнулено, например:
xalign 0.0
linear 2 xalign 1.0
linear 2 xalign 0.0
repeat 2
alpha 0.9
repeat
Тут будет плавное перемещение вправо, потом влево, затем повтор этого ещё 2 раза, потом изменение прозрачности, а после - повтор всего этого неограниченное число раз (но возврата полной непрозрачности уже нет).
На самом деле, у меня большие сомнения в том, что кто-то будет использовать в одном блоке несколько repeat
,
но такое поведение кажется мне довольно логичным, вот я его и объяснил (в Ren'Py поведение другое).
block:
# Тут любые команды.
Выполнение считается завершённым после выполнения всех команд внутри блока.
contains "images/some_bg.jpg":
size (1.0, 1.0)
contains "images/some_object.png":
pos (0.2, 0.4)
size (0.3, 0.8)
contains "images/other_object.png":
pos (0.5, 0.4)
size (0.3, 0.8)
Команда contains
удаляет все предыдущие изображения в текущем (за исключением всех предыдущих команд contains
, идущих подряд относительно текущей).
Все contains
создают новые изображения внутри текущего, они являются его потомками, их параметры (позиция, прозрачность...)
вычисляются относительно его (в общем, в данном случае, всё как и в ScreenLang).
Кстати, то, что идёт после contains
, считается за первую команду, т. е. можно первый блок из примера выше переписать так:
contains:
"images/some_bg.jpg"
size (1.0, 1.0)
И при этом ничего не изменится.
Как можно было увидеть из примера выше, сами изображения указываются обычной строкой python-кода. Самый простой способ - просто взять в кавычки путь к изображению. Но, разумеется, можно использовать и другие методы, например, что-то типа этого:
image bg some_image:
"images/some_" + config.lang + "_bg.png"
Или вместо пути к файлу изображения можно вставить имя зарегистрированной картинки, тогда на место текущей строки
будут вставлены все команды этого изображения
(опять же, идущее после знака =
в команде image
(регистрация изображения), считается первой командой этого изображения):
image bg eng_image = "images/some_eng_bg.png"
image bg cool_image:
"bg some_image"
pause 1
"bg eng_image"
pause 1
repeat
И, разумеется, добавление изображения таким образом убирает предыдущее изображение и все contains
.