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>
1.4 KiB
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).