Du bist nicht angemeldet.

Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!

Werbeanzeige

1

16.04.2016, 18:13

GameLoop: Grundlegende Fragen [C++/SFML]

Hallo Leute,

bei bisherigen Projekten mit der SFML habe ich als GameLoop immer die im "Getting Started" Tutorial gezeigte GameLoop verwendet.
Diese habe ich dann noch um eine update Funktion erweitert, damit vereinfacht gesagt, das heraus kam:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
while (window.isOpen())
    {
        sf::Event event;
        while (window.pollEvent(event))
        {
            if (event.type == sf::Event::Closed)
                window.close();
        }
        window.clear();
        float frametime = gameClock.restart().asSeconds();
        game.update(frametime);
        game.render();
        window.display();
    }


Dabei hat "game.update()" alle spiellogischen Komponenten übernommen (zB Bewegung, Eingabeverarbeitung, KI etc) und die "game.render()" hat danach alles gezeichnet.
Hat soweit auch immer alles gut funktioniert.
Da ich jetzt ein neues Projekt starten wollte und schon länger nichts mehr mit SFML gemacht habe, bin ich erst einmal im Internet auf die Suche gegangen, was denn verbreitete GameLoops sind, um es diesmal "besser" bzw "richtig" zu machen.

Demnach habe ich nun die GameLoop so umgeschrieben, dass die Update-Funktion eine konstante und die Render-Funktion eine "dynamische" Framerate hat:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
gameLogicTimeWaited = 0.0f;
gameLogicUpdateTime = 1.0f/60.0f;
while (window.isOpen())
    {
        sf::Event event;
        while (window.pollEvent(event))
        {
            if (event.type == sf::Event::Closed)
                window.close();
        }
                window.clear();
        float frametime = gameClock.restart().asSeconds();
        gameLogicTimeWaited += frametime;
        if (gameLogicTimeWaited >= gameLogicUpdateTime) 
        {
            update(); //frametime muss nicht übergeben werden, da diese konstant ist
            gameLogicTimeWaited -= gameLogicUpdateTime;
        }
        render();
                window.display();
    }


Inwiefern macht das Sinn?
Eine andere Idee wäre noch, die Update- und Render-Funktionen zu parallelisieren. Aber ich habe das Gefühl, dass durch diese unterschiedlichen Framerates es eventuell später Probleme geben könnte die bei einer gleichen Framerate nicht auftreten.

Was spricht für welches Konzept der GameLoop und habe ich eventuell noch irgendetwas gar nicht gefunden bzw bemerkt?
Wie wichtig ist das Ganze im Endeffekt?
Habt ihr schon irgendwelche (positiven/negativen) Erfahrungen mit dem ein oder anderen Konzept gemacht?

Mit freundlichen Grüßen
poorsider

Schorsch

Supermoderator

Beiträge: 5 145

Wohnort: Wickede

Beruf: Softwareentwickler

  • Private Nachricht senden

2

16.04.2016, 18:23

Hier steht einiges zu Game-loops. An sich kann man mit den Zeiten immer etwas spielen. Wenn dein Spiel zum Beispiel zu langsam läuft kannst du ein paar Frames beim rendern auslassen. Das ganze wirklich zu parallelisieren halte ich für nicht gut. Du wirst zu viel synchronisieren müssen als das du einen Vorteil davon hättest. Wobei das erst mal nur eine Vermutung ist. Ausprobiert habe ich das noch nie.
„Es ist doch so. Zwei und zwei macht irgendwas, und vier und vier macht irgendwas. Leider nicht dasselbe, dann wär's leicht.
Das ist aber auch schon höhere Mathematik.“

3

16.04.2016, 18:59

Wenn das Game entsprechend designed ist, könnte er den state kopieren (also alle wichtigen vis Daten) und damit im render thread arbeiten. Der logic thread würde dann nach jedem cycle den state mit allen wichtigen Daten befüllen.
Dann müsste man wohl nur den Austausch des States mit nem mutex absichern. Weiß nur nicht ob es das wirklich bringt :D

Werbeanzeige