@@ -55,60 +55,75 @@ func (g *Game) Update() error {
5555 newPlatPos := v.Vec {X : newPlatCenterX - platform .Half .X , Y : newPlatCenterY - platform .Half .Y }
5656 platVel = newPlatPos .Sub (platform .Pos )
5757
58- // 2. Apply gravity and check for ground collision
58+ // 2. Apply gravity
5959 boxVel .Y += Gravity
6060
61- hitInfoBoxB .Reset ()
62- relVel := boxVel .Sub (platVel )
61+ // 3. Handle player input and collision
62+ axis := examples .Axis ().Unit ()
63+ playerInputVelX := axis .X * PlayerSpeed
6364
65+ hitInfoBoxB .Reset ()
6466 onGround := false
65- if coll .BoxBoxSweep2 (platform , box , platVel , boxVel , hitInfoBoxB ) {
66- if hitInfoBoxB .Normal .Y == - 1 {
67- onGround = true
68- // When on ground, vertical velocity should be based on the platform's
69- boxVel = platVel
70- }
71-
72- moveRel := slide (relVel , hitInfoBoxB )
73- totalMove := moveRel .Add (platVel )
74- box .Pos = box .Pos .Add (totalMove )
75-
76- if hitInfoBoxB .Normal .Y == 1 { // Hit bottom of platform
77- boxVel .Y = 0
78- }
79- } else {
80- // In air
81- box .Pos = box .Pos .Add (boxVel )
67+ if coll .BoxBoxSweep2 (platform , box , platVel , boxVel , hitInfoBoxB ) && hitInfoBoxB .Normal .Y == - 1 {
68+ onGround = true
8269 }
8370
84- // 3. Handle player input
85- axis := examples .Axis ().Unit ()
8671 if onGround {
72+ // --- On-Ground Logic ---
73+ // Move box with platform first to ensure it sticks
74+ box .Pos = box .Pos .Add (platVel )
75+ // Then snap its bottom to the platform's new top position to prevent jitter/sinking
76+ box .SetBottom (platform .Top () + platVel .Y )
77+
78+ // Add player's horizontal movement
79+ box .Pos .X += playerInputVelX
80+
81+ // Update velocity for the NEXT frame
82+ boxVel .X = platVel .X + playerInputVelX
83+ boxVel .Y = platVel .Y // Y velocity matches the platform's
84+
8785 if inpututil .IsKeyJustPressed (ebiten .KeySpace ) {
88- // Jump relative to the platform's current velocity
8986 boxVel .Y += JumpForce
9087 }
91- // Add player's input speed to the platform's velocity
92- boxVel .X = platVel .X + axis .X * PlayerSpeed
9388 } else {
94- // Air control
95- boxVel .X = axis .X * PlayerSpeed
89+ // --- In-Air / Other Collision Logic ---
90+ boxVel .X = playerInputVelX // Apply air control
91+
92+ relVel := boxVel .Sub (platVel )
93+ hitInfoBoxB .Reset () // Reset for a new check
94+ if coll .BoxBoxSweep2 (platform , box , platVel , boxVel , hitInfoBoxB ) {
95+ // A collision will happen (e.g., hitting side/bottom of the platform)
96+ moveRel := slide (relVel , hitInfoBoxB )
97+ totalMove := moveRel .Add (platVel )
98+ box .Pos = box .Pos .Add (totalMove )
99+
100+ if hitInfoBoxB .Normal .Y == 1 { // Hit bottom of platform
101+ boxVel .Y = 0
102+ }
103+ } else {
104+ // No collision with platform, move freely
105+ box .Pos = box .Pos .Add (boxVel )
106+ }
96107 }
97108
98109 // 4. Update platform position
99110 platform .Pos = platform .Pos .Add (platVel )
100111
101112 // 5. Final ground check (floor)
102- if box .Bottom () > ScreenHeight {
113+ if box .Bottom () >= ScreenHeight {
103114 box .SetBottom (ScreenHeight )
104115 boxVel .Y = 0
116+ onGround = true
117+ if inpututil .IsKeyJustPressed (ebiten .KeySpace ) {
118+ boxVel .Y += JumpForce
119+ }
105120 }
106121
107122 return nil
108123}
109124func (g * Game ) Draw (screen * ebiten.Image ) {
110- examples .StrokeBox (screen , box , colornames .Green )
111- examples .StrokeBox (screen , platform , colornames .Gray )
125+ examples .FillBox (screen , box , colornames .Green )
126+ examples .FillBox (screen , platform , colornames .Gray )
112127 ebitenutil .DebugPrintAt (screen , "Controls: WASD / Space" , 10 , 10 )
113128 ebitenutil .DebugPrintAt (screen , fmt .Sprintf ("Player Velocity: %.2f" , boxVel .Y ), 10 , 30 )
114129 examples .PrintHitInfoAt (screen , hitInfoBoxB , 10 , 100 )
@@ -123,6 +138,7 @@ func main() {
123138 log .Fatal (fmt .Errorf ("error running game: %w" , err ))
124139 }
125140}
141+
126142func slide (vel v.Vec , hitInfo * coll.HitInfo ) (slideVel v.Vec ) {
127143 movementToHit := vel .Scale (hitInfo .Time )
128144 remainingVel := vel .Sub (movementToHit )
0 commit comments