Częściowo stały czy w pełni ustalony czas?

15

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?

Ryan
źródło
Całkiem dokładnie omówione tutaj: gamedev.stackexchange.com/questions/1589/...
michael.bartnett
1
Przeczytałem tę dyskusję i linki tam wiele razy. Tak właściwie doszedłem do tego postu. Moje pytanie dotyczy głównie sposobu implementacji stanów gry w celu osiągnięcia interpolacji - czego w ogóle nie omawiam w tej dyskusji.
Ryan

Odpowiedzi:

12

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

  • Użyj akumulatora czasu.
  • Użyj częstotliwości fizyki 120 Hz dla częstotliwości 60 Hz.
  • Symuluj jeden ustalony krok w przyszłość i wykorzystaj akumulację czasu, aby skorygować kod rysowania między aktualnym stanem fizyki a przyszłym stanem fizyki.
  • różne gotcha
deft_code
źródło
2

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 updatepołą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 updatejest znacznie inny niż docelowy czas render. Nierzadko zdarza się, że gry, które wymagają intensywnej updatefazy, wymagają jedynie update, powiedzmy, 10 Hz, ale renderują z pełną szybkością klatek.

Ponieważ piszesz shmup na iPhone'a, ani Twoja, updateani twoja renderpotrzeba 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ę.

Blair Holloway
źródło
Nie rozumiem Mówisz, że mogę zablokować duży dt, który wyliczyłem w mojej pętli gry - którą pochłania moja fizyka? Jak mogę to zrobić? Czy mogę to zrobić za pomocą CADisplayLink? Mam na myśli, jaki% procesora zakładasz, że używam? Czy naprawdę powinieneś założyć zablokowaną pętlę gry dt?
Ryan
To, co mówię, sprowadza się do tego: rób najmniej skomplikowane rzeczy, które by działały.
Blair Holloway
1
Opracowanie: użycie zmiennej dtdla updatei renderjest 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ływanie updateze stałym dti renderowanie z tą samą szybkością (podczas upuszczania klatek, jeśli updatedługo trwa) jest na ogół najprostszą rzeczą, która by działała. Pisanie kodu do interpolacji obiektów między updatewywołaniami zwiększa złożoność kodu; złożoność, którą dodajesz, aby rozwiązać konkretny problem.
Blair Holloway