Stop the opponent shrinking, skating and sprinting on the spot
The "smaller when swinging or tossing" was an anchor bug, not art. _fine.py scales a whole sheet so the --anchor frame is 224 px, and drawChar draws every sprite at img.height/SPRITE_H — so anchoring opponent_play on the TOSS, with arm and ball above the head, made 224 px cover the raised arm and shrank every body on that sheet. o_swing1 was 162 px against a 224 px standing pose. Each opponent batch now leads with a standing `ref` frame, which _fine.py anchors on and _regen.py discards. Correctly anchored the toss is 278 px and the man is full size; the swing is 221. The receiver no longer slides 0.12 m side to side while waiting on a serve — sliding a sprite sideways reads as skating, and the split-step swap to the run frames (removed earlier) had already been the other half of that. The idle bounce ball had one hardcoded offset for both men. They reach to opposite sides of the screen — the player is drawn from behind, the opponent from the front — so the opponent's ball sat out by his racket. dx and apex are per-man now, and o_bounce/o_bounce2 were redrawn with a patting hand to put it under. Also: the opponent wears a RED headband, and a prompt of mine that said "white" had quietly repainted it on six frames. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
1 parent
cd1c7a0cd8
commit
494bab1b69
17 files changed
+84
-14
No files matched your search
+17
@@ -467,6 +467,23 @@ the title screen. `menuMusic` passes `48`. Re-encode the file and re-measure:
|
||||
frames at 48 kHz — an un-round master, and the decoder returns 20.4787, so 7.9 ms of padding is
|
||||
trimmed). Both beds are AAC now; nothing in `assets/audio/` is still a multi-megabyte WAV.
|
||||
|
||||
**A SPRITE THAT LOOKS "SHRUNK" IS AN ANCHOR BUG, NOT AN ART BUG.** `_fine.py` scales the whole
|
||||
generated sheet so that `--anchor`'s frame is exactly 224 px, and `drawChar` then draws every sprite
|
||||
at `img.height / SPRITE_H`. So if the anchor frame is one where a PROP goes above the head, 224 px
|
||||
has to cover the prop too and every body on that sheet comes out a head short. `opponent_play` was
|
||||
`[o_toss, o_smash, o_swing1, o_swing2]` with `anchor: 0` — anchored on the TOSS, arm and ball
|
||||
stretched overhead — which is why the opponent visibly shrank whenever he served or swung
|
||||
(o_swing1 came out 162 px against a 224 px standing pose). **Every batch must lead with a plain
|
||||
standing figure via `ref`, which `_fine.py` anchors on and `_regen.py` then discards** — the shape
|
||||
the player's own batches already used. Correctly anchored, a toss frame is TALLER than 224 (278 px
|
||||
here) and the body renders at full size. Quick audit: a standing frame should be ~224, a raised-arm
|
||||
frame >224, and nothing should be well under it.
|
||||
|
||||
**The opponent wears a RED headband.** A prompt that said "white headband" silently repainted it on
|
||||
six frames, and it only showed up against the untouched `o_toss`/`o_idle1`. When regenerating part
|
||||
of a character, name his colours in the prompt AND check the regenerated frames against an untouched
|
||||
one — `check: "same"`/`"loose"` skips `colour_match`, so nothing else will catch a palette drift.
|
||||
|
||||
**The opponent was running with empty hands.** `o_run1`/`o_run2` had no racket in either fist, and
|
||||
the cause was the batch prompt: `opponent_run` never said the word "racket" and its reference sheet
|
||||
was built from the racket-less frames it was replacing, so the generator had nothing to copy one
|
||||
|
||||
Reference in new issue
Block a user