Niedawno przeczytałem ten artykuł na temat Game Loops: http://www.koonsolo.com/news/dewitters-gameloop/
A ostatnia zalecana implementacja głęboko mnie dezorientuje. Nie rozumiem, jak to działa i wygląda na kompletny bałagan.
Rozumiem zasadę: aktualizuj grę ze stałą prędkością, a wszystko, co pozostanie, renderuje grę tyle razy, ile to możliwe.
Rozumiem, że nie możesz użyć:
- Uzyskaj dane wejściowe dla 25 tyknięć
- Renderuj grę dla 975 tyknięć
Podejść, ponieważ dostaniesz wkład w pierwszą część drugiej i byłoby to dziwne? Czy to właśnie dzieje się w tym artykule?
Głównie:
while( GetTickCount() > next_game_tick && loops < MAX_FRAMESKIP)
Jak to w ogóle ważne?
Załóżmy jego wartości.
MAX_FRAMESKIP = 5
Załóżmy, że gra next_game_tick została przypisana chwilę po inicjalizacji, zanim główna pętla gry powie… 500.
Wreszcie, ponieważ używam SDL i OpenGL do mojej gry, a OpenGL służy tylko do renderowania, załóżmy, że GetTickCount()
zwraca czas od wywołania SDL_Init, co robi.
SDL_GetTicks -- Get the number of milliseconds since the SDL library initialization.
Źródło: http://www.libsdl.org/docs/html/sdlgetticks.html
Autor zakłada również, że:
DWORD next_game_tick = GetTickCount();
// GetTickCount() returns the current number of milliseconds
// that have elapsed since the system was started
Po rozwinięciu while
instrukcji otrzymujemy:
while( ( 750 > 500 ) && ( 0 < 5 ) )
750, ponieważ minął czas, odkąd next_game_tick
został przypisany. loops
wynosi zero, jak widać w artykule.
Więc weszliśmy w pętlę while, zróbmy logikę i zaakceptujmy dane wejściowe.
Yadayadayada.
Pod koniec pętli while, o której przypominam, znajduje się w naszej głównej pętli gry:
next_game_tick += SKIP_TICKS;
loops++;
Zaktualizujmy, jak wygląda następna iteracja kodu while
while( ( 1000 > 540 ) && ( 1 < 5 ) )
1000, ponieważ upłynęło czasu na uzyskanie danych wejściowych i zrobienie rzeczy, zanim dotarliśmy do kolejnego ineteracji pętli, w której wywoływana jest funkcja GetTickCount ().
540, ponieważ w kodzie 1000/25 = 40, zatem 500 + 40 = 540
1, ponieważ nasza pętla wykonała iterację raz
5 , wiesz dlaczego.
Skoro więc ta pętla While jest WYŁĄCZNIE zależna, MAX_FRAMESKIP
a nie zamierzona, w TICKS_PER_SECOND = 25;
jaki sposób gra powinna działać poprawnie?
Nie było dla mnie zaskoczeniem, że kiedy zaimplementowałem to w moim kodzie, mógłbym poprawnie dodać, ponieważ po prostu zmieniłem nazwę funkcji, aby obsłużyć dane wejściowe użytkownika i zwrócić grę do tego, co autor artykułu w swoim przykładowym kodzie, nic nie zrobił .
Umieściłem fprintf( stderr, "Test\n" );
wewnętrzną pętlę while, która nie jest drukowana do końca gry.
W jaki sposób ta pętla gry działa 25 razy na sekundę, gwarantowana, a jednocześnie renderuje tak szybko, jak to możliwe?
Dla mnie, chyba że brakuje mi czegoś OGROMNEGO, wygląda na to ... nic.
I czy ta struktura pętli while nie działa podobno 25 razy na sekundę, a następnie aktualizuje grę dokładnie tak, jak wspomniałem wcześniej na początku artykułu?
Jeśli tak jest, dlaczego nie moglibyśmy zrobić czegoś prostego, takiego jak:
while( loops < 25 )
{
getInput();
performLogic();
loops++;
}
drawGame();
I licz na interpolację w inny sposób.
Wybacz moje bardzo długie pytanie, ale ten artykuł wyrządził mi więcej szkody niż pożytku. Jestem teraz poważnie zdezorientowany - i nie mam pojęcia, jak wdrożyć właściwą pętlę gry z powodu wszystkich tych powstałych pytań.