diff options
Diffstat (limited to 'docs/tweens.org')
| -rw-r--r-- | docs/tweens.org | 90 |
1 files changed, 90 insertions, 0 deletions
diff --git a/docs/tweens.org b/docs/tweens.org new file mode 100644 index 0000000..9ac87cd --- /dev/null +++ b/docs/tweens.org @@ -0,0 +1,90 @@ +#+title: Tweens +#+author: Downstroke Contributors + +* Overview + +The =downstroke-tween= module interpolates **numeric** entity properties over wall-clock time. It is **decoupled** from the engine: you create tween values, call =tween-step= each frame from your =update:= hook, and store the returned entity back into the scene. + +Durations and delays are in **milliseconds**, matching the =dt= argument to =update:=. + +* Import + +#+begin_src scheme +(import downstroke-tween) +#+end_src + +* Core API + +** ~make-tween~ + +#+begin_src scheme +(make-tween entity #!key props duration (delay 0) ease (on-complete #f)) +#+end_src + +| Keyword | Meaning | +|---------+---------| +| ~props~ | Alist =((#:x . 200) (#:y . 40))= — keyword keys, numeric targets | +| ~duration~ | Positive integer, milliseconds of interpolation (after ~delay~) | +| ~delay~ | Non-negative integer ms before interpolation starts | +| ~ease~ | Easing symbol (see table below) or ~(lambda (t) ...)= with ~t~ in $[0,1]$ | +| ~on-complete~ | Optional ~(lambda (entity) ...)=, called **once** when the tween reaches its targets | + +Start values are captured from ~entity~ at construction time. While the tween runs, intermediate values may be **inexact** (flonums) even if starts and ends are integers. + +** ~tween-step~ + +#+begin_src scheme +(tween-step tween entity dt) +#+end_src + +Returns ~(values new-tween new-entity)~. Advance time by ~dt~ (ms). Before ~delay~ elapses, ~entity~ is unchanged. After completion, further steps return the same values (idempotent). When the tween completes, ~on-complete~ runs with the **final** entity (targets applied), then the callback slot is cleared. + +** ~tween-finished?~ / ~tween-active?~ + +Predicates on the tween struct. + +* Easing + +Each ease maps normalized time ~t ∈ [0,1]~ to an interpolation factor (usually in ~[0,1]~; ~back-out~ may exceed ~1~ briefly). + +| Symbol | Procedure | +|--------|-----------| +| ~linear~ | ~ease-linear~ | +| ~quad-in~, ~quad-out~, ~quad-in-out~ | quadratic | +| ~cubic-in~, ~cubic-out~, ~cubic-in-out~ | cubic | +| ~sine-in-out~ | smooth sine | +| ~expo-in~, ~expo-out~, ~expo-in-out~ | exponential | +| ~back-out~ | overshoot then settle (Robert Penner–style) | + +** ~ease-named~ / ~ease-resolve~ + +~ease-named~ turns a symbol into a procedure. ~ease-resolve~ accepts a symbol or procedure (identity for procedures) for use in custom tooling. + +All easing procedures are exported if you want to compose curves manually. + +* Order of operations with physics + +Tweens usually **fight** velocity and gravity if both update ~#:x~ / ~#:y~. Typical pattern: + +1. Set the entity’s ~#:skip-pipelines~ to skip integration steps you do not want (see [[physics.org][Physics]]). +2. Run ~tween-step~ for that entity. +3. Run your normal physics pipeline (collisions can still run). + +Clear ~#:skip-pipelines~ in ~on-complete~ when the tween ends. + +Example skip list for “kinematic shove” while keeping tile collisions: + +#+begin_src scheme +(entity-set player #:skip-pipelines + '(jump acceleration gravity velocity-x velocity-y)) +#+end_src + +* Demo + +=bin/demo-tweens= (source =demo/tweens.scm=) shows one row per easing and a crate that tweens horizontally while integration is skipped and tile resolution still runs. + +* Limitations (current version) + +- Single segment per tween (no built-in chains or yoyo). +- Numeric properties only. +- No engine integration — you wire ~tween-step~ yourself. |
