Spielfigur läuft spiegelverkehrt und rollt sichtbar durch den Boden hindurch #13
Labels
No labels
accessibility
bug
cleanup
consistency
crash
critical
game-feel
gameplay
high
input
level-generation
low
maintainability
medium
pause
physics
responsive
security
spec-gap
ui
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
gilli/pulse-sprint#13
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Komponente: RENDER (
poseFor,drawFigure) im Zusammenspiel mitCORE.bodyHitboxBetroffene Version:
main@9809788,index.htmlZeilen 1750–1838, 2709, 2896Befund
Zwei zusammenhängende Darstellungsfehler an der Spielfigur, gemessen am laufenden Spiel
(Playwright gegen
window.PULSE, Crops intests/.tmp/):aber beide Gelenkpärchen beugen in die gespiegelte Richtung — die Figur wirkt, als lief sie
rückwärts.
bis zu 32 px unter die Bodenkante und schwebt im Gegenzug zum Rollenstart 14 px über dem
Boden. Kontakt zum Boden gibt es in der Rollanimation praktisch nie.
Ursache
Winkel-Definition
limb()zählt den Winkel von „senkrecht nach unten“ aus nach +x:+x ist nachweislich die Fahrtrichtung:
b.x += b.vx * dt(Zeile 702), Kamerabody.x - K.PLAYER_SCREEN_X(Zeile 2712) und der Schal flattert mitdir = 1nach −x(Zeile 2899 →
anchor[0] - (26 + i * 8) * dir, Zeile 1847).1) Spiegelverkehrte Gelenkbeugung
Über 720 Samples eines vollen Laufzyklus (
poseFor("RUNNING", phase)):p.lean(Rumpf)+0.16p.legA[1]/p.legB[1](Knie)+0.34 … +0.96, nie ≤ 0p.armA[1]/p.armB[1](Ellen)−0.78 … −0.22, nie ≥ 0Das menschliche Knickt das Bein nur in Wadenrichtung (Ferse zum Gesäß) — bei senkrecht
stehendem Oberschenkel also nach −x; der Ellenbeuge beugt den Unterarm nach vorn (+x).
Die Posendaten in
poseFor(Zeilen 1761–1767 fürRUNNING, 1770–1775 fürJUMPING) notierenbeide Beugungen mit umgekehrtem Vorzeichen, sind also für eine nach links laufende Figur
geschrieben. Da der Kopf als kreisförmige Kontur keine Blickrichtung trägt, liest das Auge die
Richtung ausschließlich aus den Gelenken — und die zeigen gegen die Fahrt.
2) Roll-Pose hat keinen Anschluss an die Roll-Kollisionsbox
Die Roll-Hitbox ist bodenbündig 34 px hoch, ihr Mittelpunkt liegt auf der Hüfte:
drawFigure()dreht um genau diesen Punkt — das ist korrekt:Aber die Roll-Pose krümmt nur Arme und Beine; der Kopf bleibt auf der Stand-Geometrie
(
shoulder.y = -23,FIG.headOff = -13.6,FIG.headR = 9.6):Damit ist die gezeichnete Figur um den Drehkreis herum 49,2 px weit ausgedehnt (Silhouette
y −49,2 … +3,4 bezogen auf die Hüfte, also 52,6 px hoch), während nach unten nur
ROLL_OFF= 17 px bis zur Bodenoberfläche frei sind. Alles, was bei der Verdrehung nachunten wandert, landet im Erdreich.
Nachgerechnet (Original-Kinematik aus
FIG/limb/poseFor, Pixel gegen den gezeichnetenCanvas gemessen):
rollAnglerollAnglewächst mitvx / 30rad/s (Zeile 2709), Roll-Dauer 0,48–0,62 s(
rollDuration, Zeile 739) → 0,99 … 1,95 Umdrehungen pro Roll, davon 44 % = 0,23 s bis0,28 s mit sichtbarer Tinte unter dem Boden. Bei jeder Rollbewegung, mehrfach.
(
GATE_CLEAR46, Zeile 413) passagefrei, die Roll-Pose hält den Kopf bei kleiner Verdrehungaber bis auf 66 px über den Boden — der Kopf zeichnet also durch den Balken, obwohl die
Kollision korrekt frei ist.
Reproduktion
python3 tests/browser_flow.py-artigen Headless-Start verwenden (window.PULSE),requestAnimationFrameauf() => 0setzen.PULSE.startRun().Bildcrop um
b.x - S.camX,K.GROUND_Y: Kopf liegt vollständig unter der Bodenkante.Auch im normalen Spielbetrieb mit
S/↓auf freiem Boden sichtbar, ohne dass dieKollision etwas damit zu tun hat.
4. Befund 1:
b.phaseeinmal von0bis2πdurchziehen — nie ein Bild, in dem Knie undEllenbeuge zur Fahrtrichtung passen.
Messprotokoll (Diagnoseskripte, nicht im Repo):
Auswirkung
halb im Boden, dazu Kopfkontakt mit Balken, die es spielerisch nicht gibt.
entsteht in jeder Laufphase.
sichtbarsten Animationsgruppe.
tests/issue1.mjsnochtests/issue2.mjsnoch die Browser-Suiten prüfen die gezeichnete Sil gegen die Kollisionsbox.
Lösungsvorschlag
Zu 1 — Gelenkvorzeichen auf die Fahrtrichtung drehen (bevorzugen gegenüber spiegeln):
die zweiten Komponenten der Bein-/Arm-Paare in
poseForauf die anatomisch richtige Seiteziehen (
leg*[1]negativ,arm*[1]positiv) und dabeip.lean,p.headNodsowie dieSprungdrehung
opts.rot = clamp(-b.vy / 4200, …)(Zeile 2898) gegenprüfen. Ein pauschalesctx.scale(-1, 1)indrawFigurewürde auchaim(Hang-Ausrichtung, Zeile 1791–1796),opts.rotund die Schalrichtung mitdrehen und müsste an allen Stellen nachgezogen werden.Zu 2 — Roll-Pose wirklich einrollen: alle Gelenkpunkte müssen innerhalb des Roll-Kreises
liegen, damit die Drehung um
b.yden Boden nie schneidet. Konkret: Rumpf zur Kugel krümmen,Kopf zwischen/unter die Knie nehmen, so dass
max(|y|) ≤ ROLL_OFFüber alle Gelenke plusKopfradius gilt.
p.curl(Zeilen 1758/1783) ist als Ansatz vorhanden, wird aber nie gelesen —sinnvoll wäre ein Krümmungsfaktor, der
FIG-Längen um die Hüfte zusammenzieht. Alternativbewusst größer bauen und dann die Roll-Kollisionsbox und die Tor-Kanäle mitnehmen — das ist
aber ein Dreierpack aus
CORE.K, Tests und Commit-Notiz (Arbeitsregel 4) und verändertGATE_CLEAR-Toleranzen.Regressionstest dazu (deterministisch, ohne Browser): Posen aus
poseForüber dieZeichnungskinematik in Weltkoordinaten auflösen und fordern
GATE_CLEARüber Boden,rollAngle ∈ [0, 2π)innerhalb der Roll-Hitbox plusStrichstärken-Toleranz.
Dokumentiert in
gitlab-issues/13-laufpose-spiegelverkehrt-und-roll-clippt-durch-den-boden.md(Commit9809788).