Robię shmup na iPhone'a i próbuję zdecydować, jakiego rodzaju pętli gry użyć. Chcę użyć częściowo ustalonego timestep lub w pełni ustalonego timepep.
Z częściowo ustalonym czasem wykonania wykonam zero lub więcej wywołań aktualizacji (FIXED_INTERVAL), a następnie jedno wywołanie aktualizacji (dt), gdzie dt <= FIXED_INTERVAL na pętlę gry. Jak rozumiem, wady tej metody polegają na tym, że moja logika aktualizacji fizyki (dt) będzie trudniejsza do zaprogramowania, ponieważ zasadniczo muszę przyjmować zmienną dt dla każdej aktualizacji. A potem słyszałem również, że każdy przebieg mojej gry będzie nieco inny, ponieważ wartości zmiennoprzecinkowe nie będą takie same za każdym razem.
Następnie z całkowicie ustalonym czasem wykonania robię zero lub więcej wywołań aktualizacji (FIXED_INTERVAL), a następnie jedno wywołanie interpolacji (dt / FIXED_INTERVAL), gdzie dt <FIXED_INTERVAL na pętlę gry.
Wydaje się więc, że najważniejszą decyzją, którą naprawdę muszę podjąć, jest: czy chcę zmierzyć się z wyzwaniem związanym z wdrożeniem aktualizacji (dt) ze zmienną dt, czy też z wyzwaniem polegającym na wdrożeniu interpolacji?
Teraz, z tego co przeczytałem, większość ludzi mówi, aby używać w pełni ustalonych i interpolować. Ale kiedy myślę o implementacji interpolacji, wydaje mi się, że byłbym o wiele bardziej złożony niż aktualizacja (dt) ze zmienną dt. Jest tak, ponieważ jeśli używam interpolacji, muszę pamiętać zarówno stan poprzedni, jak i stan obecny. Więc jeśli chcę użyć interpolacji, muszę wymyślić dodatkową warstwę pośrednictwa, która wyodrębnia całe poszczególne stany gry. Podczas gdy z częściowo ustalonym czasem, w którym nie muszę używać interpolacji, nie muszę wymyślać abstrakcji stanu gry, ponieważ zawsze jest tylko jeden stan gry i są to po prostu „globalne tablice”, które reprezentują moich wrogów i wroga pociski itp.
Jaki jest więc bardziej praktyczny wybór: czy zaimplementuję go częściowo naprawiony, wiedząc, że moje aktualizacje fizyki mogą się komplikować ze zmienną dt. Czy też używam w pełni naprawionego i próbuję wymyślić abstrakcję stanu gry, aby móc śledzić poprzedni stan i aktualny stan w celu wykonania interpolacji?
Odpowiedzi:
W pełni naprawiony
Tracisz większość korzyści płynących z ustalonego czasu, rzucając zmienny krok raz na każdą klatkę.
Noel Lopis świetnie napisał o tym, jak wdrożył określony krok czasowy w swojej grze Casey's Contraptions . Jako bonus dla ciebie jest programistą iPhone'a, chociaż jego technika nie jest specyficzna dla iPhone'a.
Najważniejsze informacje z tego artykułu
źródło
To, co określasz jako „częściowo ustalony” i „w pełni ustalony”, jest moim zdaniem zarówno stałym znacznikiem czasu - dt , który przekazujesz do
update
połączenia, nie zmienia się między ramkami.Tak więc twoje pytanie brzmi „czy chcę zastosować interpolację do celów renderowania?” Odpowiedź brzmi: prawdopodobnie nie .
Interpolacja jest czymś, co chciałbyś zrobić tylko wtedy, gdy ustalony czas
update
jest znacznie inny niż docelowy czasrender
. Nierzadko zdarza się, że gry, które wymagają intensywnejupdate
fazy, wymagają jedynieupdate
, powiedzmy, 10 Hz, ale renderują z pełną szybkością klatek.Ponieważ piszesz shmup na iPhone'a, ani Twoja,
update
ani twojarender
potrzeba nie wymagają szczególnego obciążenia procesora; możesz łatwo zablokować liczbę klatek na sekundę do 30 Hz lub 60 Hz, nie zawracając sobie głowy implementacją, i nadal mieć płynnie wyglądającą grę.źródło
dt
dlaupdate
irender
jest najprostszą rzeczą, która by działała, ale generalnie unika się jej przy stosowaniu silników fizyki ze względu na niestabilność, którą powoduje. Dlatego wywoływanieupdate
ze stałymdt
i renderowanie z tą samą szybkością (podczas upuszczania klatek, jeśliupdate
długo trwa) jest na ogół najprostszą rzeczą, która by działała. Pisanie kodu do interpolacji obiektów międzyupdate
wywołaniami zwiększa złożoność kodu; złożoność, którą dodajesz, aby rozwiązać konkretny problem.