An animation is a value a graph can pick, and playing a running one makes it win again (#97)
Play, Pause and Stop animation take the animation on a port instead of a fixed setting, fed by the new Animation literal or a list item tagged `$animation`. Playing an animation already running keeps its frame but counts it as started last, so turning back to a walk that never stopped shows that walk. The actor demo walks through one Play animation over `ItemAt(walk, facing)` again and stops every animation to stand. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
1 parent
5af0a1c83a
commit
4ed2edd0f0
10 files changed
+158
-71
No files matched your search
+31
-19
@@ -7,13 +7,13 @@
|
||||
* (down, left, right, up). This demo uses the character in the top left corner, so its frames are
|
||||
* the columns 1-3 of the rows 1-4.
|
||||
*
|
||||
* Walking is one animation per direction, playing those three frames as `pingpong`
|
||||
* (left-stand-right-stand …) – the original walk cycle. Standing is not an animation at all but the
|
||||
* middle frame of the row.
|
||||
* Walking is one animation per direction over the sprite: a `texture` row keying those three frames,
|
||||
* played `pingpong` (left-stand-right-stand …) – the original walk cycle. Standing is not an
|
||||
* animation at all but the middle frame of the row.
|
||||
*
|
||||
* The graph picks a picture the way the editor does: two list variables hold the four walk
|
||||
* animations and the four standing frames, each item chosen with the texture picker, and `facing`
|
||||
* is the row index that indexes both. Nothing is built out of an id spelled by hand.
|
||||
* The graph picks the way the editor does: two list variables hold the four walk animations and the
|
||||
* four standing frames, each item chosen with its picker, and `facing` is the row index that indexes
|
||||
* both. Nothing is built out of an id spelled by hand.
|
||||
*
|
||||
* Usage: node tools/seed-actor.mjs [projectId] [baseUrl]
|
||||
*/
|
||||
@@ -68,11 +68,19 @@ const walkAnimations = DIRECTIONS.map((dir, row) => ({
|
||||
type: 'animation',
|
||||
name: `Walk ${dir}`,
|
||||
props: { fps: 8, playback: 'pingpong' },
|
||||
frames: [frameId(row, 0), frameId(row, 1), frameId(row, 2)],
|
||||
root: 'actor-sprite',
|
||||
tracks: [
|
||||
{
|
||||
id: `${WALK(dir)}-texture`,
|
||||
target: '',
|
||||
property: 'texture',
|
||||
keys: [0, 1, 2].map((column) => ({ frame: column, value: frameId(row, column) })),
|
||||
},
|
||||
],
|
||||
}));
|
||||
|
||||
/** The two lists the graph indexes: one walk animation and one standing frame per direction. */
|
||||
const WALK_PICTURES = DIRECTIONS.map((dir) => tagged('texture', WALK(dir)));
|
||||
const WALK_ANIMATIONS = DIRECTIONS.map((dir) => tagged('animation', WALK(dir)));
|
||||
const IDLE_PICTURES = DIRECTIONS.map((_, row) => tagged('texture', idleFrame(row)));
|
||||
|
||||
/**
|
||||
@@ -129,9 +137,10 @@ const nodes = [
|
||||
face('c-up', 'up', 1920, 940),
|
||||
face('c-down', 'down', 1920, 1080),
|
||||
|
||||
// What the sprite shows. Both picture lists are indexed by the row the character faces, so there
|
||||
// is one node per list and no branch per direction.
|
||||
// Setting the same animation again lets it keep running, so writing it every frame is free.
|
||||
// What the sprite shows. Both lists are indexed by the row the character faces, so there is one
|
||||
// node per list and no branch per direction. Playing a running walk again keeps its frame but makes
|
||||
// it the one that wins, so turning back to a walk still running shows that walk. Standing stops
|
||||
// every animation and wears the standing frame.
|
||||
node('br-move', 'Branch', 1460, 1280),
|
||||
node('v-pics', 'Variables', 1400, 1480, {}, [
|
||||
port('walk', 'list'),
|
||||
@@ -140,8 +149,9 @@ const nodes = [
|
||||
]),
|
||||
node('pick-walk', 'ItemAt', 1680, 1430),
|
||||
node('pick-idle', 'ItemAt', 1680, 1640),
|
||||
node('wear-walk', 'Properties', 1920, 1280, propertiesOf('sprite'), [written('texture', 'texture')]),
|
||||
node('wear-idle', 'Properties', 1920, 1510, propertiesOf('sprite'), [written('texture', 'texture')]),
|
||||
node('play-walk', 'PlayAnimation', 1920, 1280),
|
||||
node('stop-walk', 'StopAnimation', 1920, 1510),
|
||||
node('wear-idle', 'Properties', 2160, 1510, propertiesOf('sprite'), [written('texture', 'texture')]),
|
||||
];
|
||||
|
||||
const edges = [
|
||||
@@ -198,12 +208,14 @@ const edges = [
|
||||
edge('e48', 'v-pics', 'facing', 'pick-walk', 'index'),
|
||||
edge('e49', 'v-pics', 'idle', 'pick-idle', 'list'),
|
||||
edge('e50', 'v-pics', 'facing', 'pick-idle', 'index'),
|
||||
edge('e51', 'br-move', 'then', 'wear-walk', 'exec'),
|
||||
edge('e52', 'owner', 'object', 'wear-walk', 'object'),
|
||||
edge('e53', 'pick-walk', 'item', 'wear-walk', 'texture'),
|
||||
edge('e54', 'br-move', 'else', 'wear-idle', 'exec'),
|
||||
edge('e51', 'br-move', 'then', 'play-walk', 'exec'),
|
||||
edge('e52', 'owner', 'object', 'play-walk', 'object'),
|
||||
edge('e53', 'pick-walk', 'item', 'play-walk', 'animation'),
|
||||
edge('e54', 'br-move', 'else', 'stop-walk', 'exec'),
|
||||
edge('e55', 'owner', 'object', 'wear-idle', 'object'),
|
||||
edge('e56', 'pick-idle', 'item', 'wear-idle', 'texture'),
|
||||
edge('e57', 'owner', 'object', 'stop-walk', 'object'),
|
||||
edge('e58', 'stop-walk', 'exec', 'wear-idle', 'exec'),
|
||||
];
|
||||
|
||||
const sheet = await uploadTexture(baseUrl, SHEET_FILE);
|
||||
@@ -251,11 +263,11 @@ const project = {
|
||||
id: 'player',
|
||||
type: 'behavior',
|
||||
name: 'Player',
|
||||
props: { speed: SPEED, facing: 0, walk: WALK_PICTURES, idle: IDLE_PICTURES },
|
||||
props: { speed: SPEED, facing: 0, walk: WALK_ANIMATIONS, idle: IDLE_PICTURES },
|
||||
variables: [
|
||||
variable('speed', 'number', SPEED),
|
||||
variable('facing', 'number', 0),
|
||||
variable('walk', 'list', WALK_PICTURES),
|
||||
variable('walk', 'list', WALK_ANIMATIONS),
|
||||
variable('idle', 'list', IDLE_PICTURES),
|
||||
],
|
||||
graph: { nodes, edges },
|
||||
|
||||
Reference in new issue
Block a user