tools/seed-actor.mjs builds the project Actor demo: it uploads tools/assets/Actor1.png, slices the 576x384 sheet into the 96 cells of a 12x8 grid (48x48 each, no remainder) and wears the character in the top left corner. Walking is four ping-pong animations of three frames, which is the original RPG-Maker walk cycle; standing is the middle frame of the row, not an animation. The graph pastes walk- or idle- in front of the direction faced and wears the result, so eight cases need no branch tree - the List node only holds numbers. Which way it looks is the key pressed last, corrected whenever only one axis is still held, or letting go of one key of a diagonal would walk backwards. Axis input already normalizes its vector. tools/lib/projects.mjs gains uploadTexture, since data/textures/ is git-ignored and a seed that ships its picture has to send it. The harness gains w/a/s/d and keyDown/keyUp halves, because holdKey cannot express two presses that overlap - which is what a diagonal is. tools/smoke-actor.mjs plays it in 19 checks and reads the drawn pixels at the camera edge, where the bounds hold him walking on the spot: three distinct frames walking, one standing. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
21 lines
1.4 KiB
Markdown
21 lines
1.4 KiB
Markdown
Ein Sprite, das ein Frame aus einem Sheet zeigt, zeichnet am Rand eine Pixelzeile, die zum
|
||
Nachbarframe gehört. Sichtbar im Projekt *Actor demo* als heller Streifen über dem Kopf.
|
||
|
||
Gemessen (`__gm.pixelAt`, Spielansicht): Beim Stehen nach unten (Sheet-Zeile 0, deren oberste
|
||
Pixelzeile in der Datei komplett leer ist) liegt dort `#394349` – bläulich. Das passt zur
|
||
*untersten* Sheet-Zeile (Schuhe von Character 6, `(87,87,154)`) über den grünen Hintergrund
|
||
gemischt, die Kante bricht also auf die Gegenseite um. Beim Laufen nach rechts (Zeile 2) ist der
|
||
Streifen stattdessen hellgrau – die Füße aus Zeile 1 direkt darüber.
|
||
|
||
Ursache: `frameFillMatrix` (`src/viewport/textureFill.ts`) bildet die **ganze** Textur auf die Shape
|
||
ab, weil Pixi-v8-Graphics-Fills `Texture.frame` ignorieren. Eine Fill-Matrix kann keine Grenze
|
||
ausdrücken, also sampelt die Randzeile in den Nachbarn, sobald die Skalierung nicht ganzzahlig ist
|
||
(die Spielansicht streckt 640×360 auf etwa 735×409, Faktor ~1,13).
|
||
|
||
Nicht die Ursache: die Frame-Rechtecke. Die sind exakt ganzzahlig; den fraktionalen Fall behandelt
|
||
`normalizeFrameRect` bereits.
|
||
|
||
Abzuklären: halber Pixel Einzug in der Matrix (kostet einen halben Pixel Bildinhalt, trifft jedes
|
||
Frame) oder ein echtes `Sprite` mit `new Texture({source, frame})` statt des Graphics-Fills (Pixi
|
||
klemmt dann selbst, ändert aber den Zeichenweg für alle Sprites).
|