From c02aa7e5315bda898f9ecd1587f54def49d7ebce Mon Sep 17 00:00:00 2001 From: meleki Date: Thu, 1 Oct 2026 10:57:44 +0200 Subject: [PATCH] Describe Animation playing and Animation length (#233) - Animations: what the two nodes answer in each playback, what None asks for, and where the rule lives. - Behaviors: both nodes in the node list. - Development: 1615 editor checks. --- Animations.md | 26 ++++++++++++++++++++++++++ Behaviors.md | 2 +- Development.md | 2 +- 3 files changed, 28 insertions(+), 2 deletions(-) diff --git a/Animations.md b/Animations.md index 13fa2cf..d0d64ad 100644 --- a/Animations.md +++ b/Animations.md @@ -150,6 +150,32 @@ values stay those of its first start, so a relative row does not add up. Played every frame, an animation never gets past its first frame — use it on a single event such as a key press. +**Asking whether it still runs.** `Animation playing` is a data node with the inputs *object* and +*animation* and three answers, read at the moment they are asked for — right after a `Play animation` +in the same pulse it already says yes: + +- **playing** is on while the animation runs. A paused one does not run, and neither does one that + `Stop animation` ended or is fading out. A *Once (reset)* pass blending back to where it started still + runs: it still shows. In the frame `On animation finished` fires for a *Once* animation it is off. +- **progress** is where the playhead stands on the timeline, 0 to 1, in every playback. On *Loop* it + starts over with each pass; on *Ping-pong* it rises to 1 at the last key and falls again on the way + back. +- **time left (s)** is the time until the playhead reaches the end of its pass: the end of the + animation for the two *Once* modes, with *blend out (s)* added for *Once (reset)*; the end of the + round on *Loop*; the next turn on *Ping-pong*. A paused animation keeps its place and its time left. + +Leave *Animation* at None to ask for whatever runs on the object: the animation started last among +those running, or the one started last at all when none runs. With no object, or an animation that is +not on it, the answers are off, 0 and 0. So "no new attack while the swing runs" is one `Branch` on +`playing` instead of a timer that has to repeat the animation's length. + +`Animation length` gives the seconds one pass takes, from the timeline and the frame rate alone — for +a cooldown that is meant to be longer than the animation (`length + 0.1`). + +Under the hood: the rule is `playerStatus` and `leadingPlayer` in `src/core/model/animation.ts`; the +nodes reach the animation through `GraphLookup.animation`, which hands a run only the frame count, +the frame rate and the playback. + **It runs in play only.** The Scene and Container tabs show the objects as stored; the edit mode has no clock. The fastest way in is right-clicking a texture → **Create animation from texture**, which makes a sprite of the texture and an animation over it with a `texture` row keyed frame by diff --git a/Behaviors.md b/Behaviors.md index 252024f..4f081af 100644 --- a/Behaviors.md +++ b/Behaviors.md @@ -228,7 +228,7 @@ playing use the same two words. normalized direction, so diagonals are not faster), `Compare` (two numbers count as equal up to float noise, a relative 1e-9, so `time - late == 6` holds without a `Round`; `Equals` does the same for two numbers, and for a number against a typed text that is a number, like `130`), `And/Or/Not`, `Key is down`, - `Mouse position`, `Mouse button`, `Is hovered`, `Is touching`, `Get velocity`, `Current state` (name and id), `Is in state` (one boolean per state) · + `Mouse position`, `Mouse button`, `Is hovered`, `Is touching`, `Animation playing` (whether an animation runs on an object, its progress and time left) and `Animation length` (see [Animations](Animations)), `Get velocity`, `Current state` (name and id), `Is in state` (one boolean per state) · actions `Move` (dx, dy, scale, dt — connect an event's dt for per-second movement; in the object's own axes, which a turned parent turns too; with *Collide with solids* it slides along what it hits, less friction, and outputs `blocked x/y`, `hit` and the contact `normal x/y`, see [Colliders](Colliders)), `Set position`, `Spawn` (asset input + x/y/z, optional parent → outputs the new object; the asset is picked on the node or arrives over an edge, from an `Asset` node, a variable or a list item. A pick saved while it was still a setting reads as that input's value, so older projects spawn as before; the same holds for the asset of `Is asset`), `Destroy` (removes the object with everything below it; with **keep children** on, only the object goes: its children move up to its parent (top level when it had none) and keep their place, rotation and size in the world, and the output `children` is the list of them, nearest level only. Its behaviors and its rigidbody go with it either way. In the editor run, children that are content of a placed container move up for the run only: their place belongs to the template, so the scene does not learn it), `Emit` (starts a particle source over, see *Particles*), `Play sound` / `Stop sound` (see [Sounds](Sounds): the asset says how loud and whether it loops, the node's diff --git a/Development.md b/Development.md index 89e373f..710d2cc 100644 --- a/Development.md +++ b/Development.md @@ -18,7 +18,7 @@ php tests/php/accounts.test.php # the API's accoun # has and the web server's container has not (SKIP there) php tests/php/snapshots.test.php # the snapshot store (#231), the same way php tests/php/releases.test.php # the release store (#266), the same way -node tools/seed-e2e.mjs && node tools/e2e.mjs # 1613 editor checks, screenshots in /tmp/gm-e2e-*.png +node tools/seed-e2e.mjs && node tools/e2e.mjs # 1615 editor checks, screenshots in /tmp/gm-e2e-*.png GM_STEPS=20 node tools/e2e.mjs # or 1-12, or 6,20 — a subset while working on one step ./e2e.sh start [GM_STEPS] # the same run detached, see below ./e2e.sh status # live progress, or the last run's result