SFML 2.5 - Charakter bewegen

SFML 2.5 - Charakter bewegen

Wie bewegt man einen Sprite in SFML?

Einen Charakter mit SFML 2.5 zu bewegen ist keine große Kunst.

sprite.move(1.f, 0);

Mehr als diese Zeile wird nicht benötigt. Vielen Dank fürs Lesen.

Spaß beiseite! Ja, mehr wird theoretisch nicht benötigt, in der Praxis will man aber dass sich der Charakter auf jedem Endgerät identisch bewegt. Das wäre so nämlich nicht der Fall.

Um zu erreichen, dass sich ein Sprite auf allen Endgeräten mit konstanter Geschwindigkeit bewegt, benötigt man den Faktor der auf allen Endgeräten variabel ist: Die Framerate.

Geschwindigkeit und Framerate

Von der Framerate sollte jeder schon mal gehört haben, der einen Computer, Fernseher oder eine Konsole besitzt. Die Framerate ist die Anzahl der Bilder die pro Sekunde angezeigt werden kann, Hardware bedingt. Auch frames per second oder kurz fps genannt.

Framerate in Videospielen

Die Framerate ist in Videospielen, vor allem Online Multiplayer Spielen sehr wichtig. Denn während einige Spieler ein flüssiges Spielerlebnis haben, leiden andere unter geringer fps und Frameeinbrüchen. Gerade bei Multiplayer Spielen würde das zu unfairen Nachteilen und Vorteilen führen. Um das zu minimieren, muss also die Framerate beachtet werden. Diese zu berechnen ist kein Hexenwerk. Wir brauchen lediglich die Millisekunden, die für einen kompletten Gameloop Durchlauf benötigt werden. Die Zeit für den letzten Schleifendurchlauf wird dann bei allen relevanten Bewegungen einbezogen.

Das Problem lösen

float charSpeed = 2.f;

while(app.isOpen())
{
// ...
character.move(charSpeed, 0);

app.clear(sf::Color::White);
app.draw(character);
app.display();
}

Desto höher die Framerate, desto öfter wird der Inhalt zwischen den geschweiften Klammern ausgeführt. Das bedeutet im Umkehrschluss, dass bei einem langsamen Rechner mit 10fps, die move Funktion maximal 10 mal per Sekunde aufgerufen wird. Während ein schneller Rechner mit 60fps die move Funktion 60 mal per Sekunde aufrufen kann. Somit sind die Sprites nach einer Sekunde an zwei verschiedenen Positionen in der Spielwelt. Genau das ist das Problem.

Framerate miteinbeziehen

float charSpeed = 2.f;
sf::Clock frametimeClock;
float frametime = 0;

while(app.isOpen())
{
// ...
**character.move(charSpeed * frametime, 0);

app.clear(sf::Color::White);
app.draw(character);
app.display();

**frametime = frametimeClock.getElapsedTime().asSeconds();
**frametimeClock.restart();
}

Machen wir ein Beispiel. Der erste Gameloop Durchlauf braucht 0.3s, der zweite 0.2s und der dritte 0.5s. Das würde bedeuten:

  • charSpeed * 0.3s = 2 * 0.3 = 0.6
  • charSpeed * 0.2s = 2 * 0.2 = 0.4
  • charSpeed * 0.5s = 2 * 0.5 = 1

Wenn man diese Werte addiert, erhält man, oh Wunder: 2. Das bedeutet also, nach genauer einer Sekunde, bewegt sich der Charakter in der Spielwelt um 2 Einheiten auf der X Achse. Auf jedem Endgerät. Bei jeder Framerate.

Hinterlasse gerne einen Like oder Kommentar (~‾▿‾)~
Name Text