ci / release (push) Successful in 5m5s
ci-platforms / build (amd64, windows, windows-2022) (push) Skipped
ci-platforms / build (arm64, darwin, macos-15) (push) Skipped
ci-platforms / build (amd64, darwin, macos-15-intel) (push) Skipped
ci / checks (push) Successful in 4m41s
ci / build (amd64, linux, ubuntu-24.04) (push) Successful in 7m14s
The remaining editor strings and undo step names; component, field, enum, setting, diagnostic and Script API texts under schema.*, enum.*, setting.*, diag.* and api.*; the launcher, the in-game Settings View with a Language setting, the CLI and aego schema show --lang. Every documentation page has a .ru.md translation; the site has a full Russian tree with hreflang, a language switch and ru/llms.txt; aego docs check --lang ru. New doc.tutorial and doc.recipe icons. Fix: an animator restored by a rewind prepares its controller before the replayed step.
166 lines
10 KiB
Markdown
166 lines
10 KiB
Markdown
---
|
||
id: tween
|
||
title: Твины и таймеры
|
||
---
|
||
# Твины и таймеры
|
||
|
||
Твин переводит одно свойство узла из текущего значения в целевое за заданное время; таймер отсчитывает время и срабатывает. Оба работают в игре и в `aego run`, принадлежат игровому миру и после создания ничего не выделяют на кадр.
|
||
|
||
import (
|
||
"aego/curve"
|
||
"aego/timer"
|
||
"aego/tween"
|
||
)
|
||
|
||
func Hurt() coroutine {
|
||
yield tween.ToColor(node, "SpriteRenderer.Tint", HitTint, 0.1, curve.OutQuad)
|
||
yield tween.ToColor(node, "SpriteRenderer.Tint", Color{1, 1, 1, 1}, 0.3, curve.InQuad)
|
||
}
|
||
|
||
---
|
||
id: tween/paths
|
||
title: Пути к свойствам
|
||
---
|
||
# Пути к свойствам
|
||
|
||
Твин называет своё свойство путём, который разрешается один раз при старте твина.
|
||
|
||
| Путь | Свойство |
|
||
|---|---|
|
||
| `SpriteRenderer.Tint` | поле компонента; короткое имя компонента подходит, если оно уникально, иначе пишите `render2d.SpriteRenderer.Tint` |
|
||
| `SpriteRenderer.Tint.a` | одна составляющая вектора или цвета: `x y z w` или `r g b a` |
|
||
| `transform.position`, `transform.rotation`, `transform.scale` | локальная трансформация, 2D или 3D |
|
||
| `script/Player.Speed`, `script/mygame.player.Player.Speed` | экспортированное или закрытое поле скрипта на узле |
|
||
|
||
Имена полей принимаются как в схеме (`tint`) или с заглавной первой буквой (`Tint`). Твинятся значения `float` и `int` (с округлением), `Vec2`, `Vec3`, `Color`, `Rect`, `Quat` (по кратчайшей дуге). Строки, перечисления, ссылки, поля только для чтения и списки не твинятся. Неверный путь или значение не того типа останавливает вызывающий скрипт с `AES6010` и возвращает `nil`.
|
||
|
||
Твин трансформации динамического физического тела — это телепорт на следующем шаге физики; двигайте тела скоростью.
|
||
|
||
---
|
||
id: tween/scripts
|
||
title: Твины в скриптах
|
||
---
|
||
# Твины в скриптах
|
||
|
||
Твин меняет одно свойство узла от текущего значения до целевого за заданную длительность. Скрипты запускают твины функциями `aego/tween` и цепляют параметры к результату.
|
||
|
||
```aes
|
||
tween.ToFloat(node, "SpriteRenderer.Tint.a", 0, 0.5, curve.Linear).Delay(1).PingPong(-1)
|
||
```
|
||
|
||
- `ToFloat`, `ToVec2`, `ToVec3`, `ToColor` и `ToQuat` анимируют свойство по его пути. `Position` двигает 2D-узел.
|
||
- Сглаживание — пресет из `aego/curve`, например `curve.OutQuad` или `curve.OutBack`. `Curve` берёт вместо него поле-кривую.
|
||
- Параметры, такие как `Delay`, `Loop`, `PingPong` и `Unscaled`, идут сразу после вызова.
|
||
- `Completed` — сигнал, который срабатывает один раз, когда твин заканчивается.
|
||
|
||
Все функции и параметры перечислены на странице [aego/tween](ref:aego/tween).
|
||
|
||
## Правила
|
||
|
||
- Когда заканчивается последний отрезок, свойство получает точно конечное значение: `to` или начальное после чётного числа отрезков туда-обратно.
|
||
- Новый твин того же свойства того же узла останавливает текущий.
|
||
- Твин останавливается, когда пропадает его узел, компонент или скрипт.
|
||
|
||
---
|
||
id: tween/timers
|
||
title: Таймеры
|
||
---
|
||
# Таймеры
|
||
|
||
var attack timer.Timer
|
||
|
||
func Ready() {
|
||
attack = timer.Cooldown(0.4)
|
||
}
|
||
|
||
func Update(dt float) {
|
||
if input.Pressed("Fire") && attack.Use() {
|
||
shoot()
|
||
}
|
||
}
|
||
|
||
| Функция | |
|
||
|---|---|
|
||
| `timer.Start(s) Timer` | одноразовый таймер; он освобождается, когда срабатывает |
|
||
| `timer.New(s) Timer` | таймер, который остаётся после окончания, чтобы `Restart` мог запустить его снова |
|
||
| `timer.Cooldown(s) Timer` | стартует готовым; `Use()` забирает его и начинает ожидание |
|
||
|
||
| Метод | |
|
||
|---|---|
|
||
| `Repeat(n) Timer` | сработать `n` раз, `-1` — до `Cancel` |
|
||
| `Unscaled() Timer` | считать реальное время |
|
||
| `Pause()`, `Resume()`, `Restart() bool`, `Cancel()` | управление |
|
||
| `Done() bool`, `Remaining() float`, `Count() int` | состояние |
|
||
| `Ready() bool`, `Use() bool` | перезарядка |
|
||
| `Fired(count int)` | сигнал при каждом срабатывании |
|
||
|
||
Таймер, созданный скриптом, принадлежит узлу этого скрипта и отменяется, когда узел уничтожается. `Restart` у одноразового таймера, который уже сработал, ничего не делает: его слота больше нет. Для таймеров, которые вы перезапускаете, используйте `timer.New`.
|
||
|
||
---
|
||
id: tween/waiting
|
||
title: Ожидание в корутинах
|
||
---
|
||
# Ожидание в корутинах
|
||
|
||
`yield` ждёт твин или таймер:
|
||
|
||
func Die() coroutine {
|
||
yield tween.ToFloat(node, "SpriteRenderer.Tint.a", 0, 0.2, curve.OutQuad)
|
||
node.Destroy()
|
||
}
|
||
|
||
func Spawner() coroutine {
|
||
t := timer.New(2).Repeat(-1)
|
||
for {
|
||
yield t
|
||
spawn()
|
||
}
|
||
}
|
||
|
||
Как продолжается ожидание:
|
||
|
||
- `yield t` продолжается на кадре после того, как твин закончился или остановлен либо таймер сработал или отменён.
|
||
- Повторяющийся таймер будит корутину при каждом срабатывании.
|
||
- Дескриптор `nil` или уже завершённый продолжает на следующем кадре.
|
||
- Разбуженные корутины выполняются вместе с остальными корутинами игрового времени, поэтому они ждут, пока игра на паузе, даже если сам твин или таймер не зависит от масштаба времени. В меню паузы ждите через `yield waitUnscaled(s)`.
|
||
|
||
Опроса нет: корутина, ждущая дескриптор, ничего не стоит, пока дескриптор её не разбудит.
|
||
|
||
---
|
||
id: tween/actions
|
||
title: Действия
|
||
---
|
||
# Действия
|
||
|
||
Действие запускает твины и таймеры по очереди или одновременно:
|
||
|
||
yield action.Sequence().
|
||
Then(tween.Position(node, Vec2{4, 0}, 0.5, curve.OutCubic)).
|
||
Wait(0.2).
|
||
Then(tween.ToFloat(node, "SpriteRenderer.Tint.a", 0, 0.3, curve.Linear))
|
||
|
||
| Функция или метод | |
|
||
|---|---|
|
||
| `action.Sequence()`, `action.Parallel()` | новое действие; оно стартует при следующем обновлении твинов |
|
||
| `Then(tween)`, `ThenTimer(timer)`, `ThenAction(action)`, `Wait(s)` | шаги, добавляемые до старта действия |
|
||
| `Stop()`, `Done()`, `Running()` | управление и состояние |
|
||
| `Completed(finished bool)` | сигнал, когда действие заканчивается |
|
||
|
||
Твин или таймер, переданный в `Then`, должен быть создан в том же кадре и не принадлежать другому действию; он ждёт своей очереди. Шаг, который закончился раньше, считается выполненным. `Stop` останавливает все незаконченные шаги и завершает действие с `finished=false`. Действие останавливается, когда умирает узел скрипта, который его создал. Корутина ждёт действие через `yield a`; действие не может ждать корутину.
|
||
|
||
---
|
||
id: tween/go
|
||
title: Go
|
||
---
|
||
# Go
|
||
|
||
tw := sdk.TweensOf(ctx)
|
||
h, err := tw.ToVec2(node, "transform.scale", sdk.Vec2{X: 1.2, Y: 1.2}, 0.1, sdk.TweenOptions{Ease: curve.OutBack, Legs: 2, PingPong: true})
|
||
t, _ := tw.StartTimer(1.5, sdk.TimerOptions{Repeat: -1, Owner: node})
|
||
|
||
У `TweenOptions` есть `Ease`, `Curve`, `Delay`, `Legs`, `PingPong` и `Unscaled`. У `TimerOptions` есть `Repeat`, `Unscaled`, `Keep` и `Owner`. Дескрипторы — значения; устаревший дескриптор читается как завершённый.
|
||
|
||
Системы `tween.game` (PostUpdate, останавливается на паузе) и `tween.unscaled` (PostUpdate, работает всегда) продвигают пулы. Модуль, который выдаёт свои дескрипторы для ожидания, регистрирует их через `sdk.ScriptHandle` и вызывает `scriptwait.Waker.Complete`, когда объект заканчивается (см. «Нативные привязки» в справочнике языка).
|
||
|
||
`OnCompleted(h, func(finished bool))` и `OnFired(h, func(count int))` подключают код на Go к тем же сигналам и возвращают `Connection` для `Disconnect`.
|