Hallo Zusammen,
ich habe mittlerweile auf vielen Seiten etwas über Gameloops gelesen und habe dann auch nach einiger zeit eine halbwegs vernünftige hinbekommen.
Erst mal der Code:
Die Methoden GetTimeMS() bzw. GetTimeNS() liefern einen Zeitstempel in milli- bzw. nanosekunden als __int64.
Fragen:
1)
Sollte ich überhaupt so eine Gameloop verwenden (den test block erst mal ausgeschlossen)?
Ich könnte ja auch einfach so begrenzen:
aber dann habe ich wieder das problem mit dem Updaten da ich keine zeit habe die ich der UpdateGame() methode übergeben kann. Damit währe es dann so dass bei schnelleren pcs das Spiel sich schneller aktualisiert oder wartet es einfach bei
window.display() bis es zeit ist das spiel zu aktualisieren?
2)
HandleEvents(&window);
Dieser Aufruf arbeitet alle events von der warteliste ab.
(Das mit screens und so leitet nur den Aufruf weiter damit nur ein bestimmter Menübildschirm oder ein bestimmter Gamebildschirm updatet wird sonst würde es bei großen Projekten immer alles updaten und das will ich nicht(Performance))
Jetzt zur Frage:
Wenn die Eventschleife zu viel Events zu verarbeiten hat wie z.B. wenn ich das Fenster mit der Maus verschiebe habe ich natürlich massive Framerateeinbußen. Sollte ich daher die Eventschleife in einem anderen Thread oder so ausführen? dann bekomme ich aber wieder Probleme mit Zugriffsfehlern und was weiß ich allem. Oder gibt es eine andere Möglichkeit?
3)
es geht um den Testblock (die zwei Zeilen die in den test Kommentaren stehen)
Sollte ich überhaupt "deltaTime" immer aktualisieren?
Meine Idee war dass es bei jeden Frame die Geschwindigkeit des Updaters anpasst und so zeitliche Bewegungen im spiel noch präziser ausgeführt werden.
Danke und Grüße,
Rooky420
ich habe mittlerweile auf vielen Seiten etwas über Gameloops gelesen und habe dann auch nach einiger zeit eine halbwegs vernünftige hinbekommen.
Erst mal der Code:
Code:
void GameManager::GameLoop()
{
_running = true;
sf::RenderWindow window(sf::VideoMode(800, 600, 32), "Game");
const long TARGET_FPS = 60;
const double NANO_SECOND = 1000000000;
const __int64 NANO_SECOND_FPS = NANO_SECOND / TARGET_FPS;
float deltaTime = 1.0f / TARGET_FPS;
__int64 startFPSTime = GetTimeMS();
int numFrames = 0;
while (window.isOpen())
{
__int64 frameStartTime = GetTimeNS();
HandleEvents(&window);
if (!_running)
break;
UpdateGame(deltaTime);
window.clear();
RenderGame(&window);
window.display();
numFrames++;
if (GetTimeMS() - startFPSTime >= 1000)
{
std::cout << "Frames: " << numFrames << std::endl;
startFPSTime = GetTimeMS();
numFrames = 0;
}
__int64 neededTimeNS = (GetTimeNS() - frameStartTime);
//test
__int64 expectedFramerate = (neededTimeNS * TARGET_FPS) / NANO_SECOND;
deltaTime = 1.f / expectedFramerate;
//endtest
__int64 sleepDuration = NANO_SECOND_FPS - neededTimeNS;
if (sleepDuration > 0)
{
std::this_thread::sleep_for(std::chrono::nanoseconds(sleepDuration));
}
}
}
Die Methoden GetTimeMS() bzw. GetTimeNS() liefern einen Zeitstempel in milli- bzw. nanosekunden als __int64.
Fragen:
1)
Sollte ich überhaupt so eine Gameloop verwenden (den test block erst mal ausgeschlossen)?
Ich könnte ja auch einfach so begrenzen:
Code:
window.setFramerateLimit(60);
window.display() bis es zeit ist das spiel zu aktualisieren?
2)
HandleEvents(&window);
Dieser Aufruf arbeitet alle events von der warteliste ab.
Code:
void GameManager::HandleEvents(sf::RenderWindow * window)
{
sf::Event event;
while (window->pollEvent(event))
{
auto screen = screens->GetAktScreen();
if(screen != NULL)
screen->Event(&event);
if (event.type == sf::Event::Closed)
{
delete manager;
window->close();//Call all Destructors before
}
}
}
Jetzt zur Frage:
Wenn die Eventschleife zu viel Events zu verarbeiten hat wie z.B. wenn ich das Fenster mit der Maus verschiebe habe ich natürlich massive Framerateeinbußen. Sollte ich daher die Eventschleife in einem anderen Thread oder so ausführen? dann bekomme ich aber wieder Probleme mit Zugriffsfehlern und was weiß ich allem. Oder gibt es eine andere Möglichkeit?
3)
es geht um den Testblock (die zwei Zeilen die in den test Kommentaren stehen)
Sollte ich überhaupt "deltaTime" immer aktualisieren?
Meine Idee war dass es bei jeden Frame die Geschwindigkeit des Updaters anpasst und so zeitliche Bewegungen im spiel noch präziser ausgeführt werden.
Danke und Grüße,
Rooky420