Wie wird die Spielelogik alle 100 ms ausgeführt, aber so schnell wie möglich gerendert?

7

Ich habe einen einfachen Schlangenklon erstellt und möchte die Spielelogik alle 100 ms ausführen, während ich so schnell wie möglich rendere. Wie kann ich dies erreichen, wenn das Programm möglicherweise mit sehr unterschiedlichen Bildraten ausgeführt wird?

Wenn ich zum Beispiel den Code in eine native ausführbare Datei kompiliere, habe ich über 1000, wo ich einfach warten kann, bis 100 ms vergangen sind, bevor ich den nächsten logischen Schritt ausführe. Beim Kompilieren auf asm.js erhalte ich jedoch Bildraten von etwa 20, was bedeutet, dass die Zeitspanne zwischen zwei logischen Schritten zwischen 100 ms und 149 ms liegen kann, was zu sichtbarem Ruckeln führen würde (eine Bewegung ist schneller als eine andere).

ooxi
quelle
Haben Sie feste Zeitschritte und variable Zeitschritte untersucht?
MichaelHouse
Sie können die InvokeRepeating verwenden , um die Funktion auszulösen und sie zu einem Sonderpreis zu wiederholen
Sata
InvokeRepeatingNähte als Feature Unity oder Maby C #, aber ich benutze C. Trotzdem danke :)
Ooxi
Warum sollten Sie schneller als Ihr Update-Schritt rendern? Wenn sich nichts geändert hat, warum den Bildschirm aktualisieren?
Niels

Antworten:

2

Dies ist ein grundlegendes Beispiel für die Berechnung der Framerate.
Ich gehe davon aus, dass es eine Funktion namens current_milliseconds()gibt, die die Anzahl der Millisekunden vom Beginn des Programms zurückgibt.

/* Before the loop */
int time = current_milliseconds(); // Setting up the Timer
int FPS = 60;

/* Inside the loop (at the bottom) */
int frame_ms = current_milliseconds() - time; // Milliseconds the frame took to render
// Calculating the number of frames the machine could render in 1 second at that speed
FPS = 1000.0 / (frame_ms <= 0 ? 1 : frame_ms);
time = current_milliseconds();

Mein Rat aus persönlicher Erfahrung: Begrenzen Sie die Framerate NICHT manuell. Es ist besser für Sie, den Zeitpunkt des Renderns jedes Frames zu überprüfen und Ihre Spielelogik entsprechend anzupassen.
Eine andere Lösung besteht darin, vSync zu verwenden, um eine konstante Framerate zu erhalten.

Xriuk
quelle
"Es ist besser für Sie, den Zeitpunkt des Renderns jedes Frames zu überprüfen und Ihre Spiellogik entsprechend anzupassen" - dies hängt empfindlich von den Kriterien ab, die zur Definition von "besser" verwendet werden. Wenn eines Ihrer Kriterien deterministisches Verhalten ist, um die Synchronisation zwischen mehreren Clients zu minimieren, oder wenn Sie ein konsistentes Gameplay auf einer Vielzahl von Geräten mit unterschiedlicher Leistung wünschen, ist es nicht unbedingt besser, die Spielelogik mit einer variablen Framerate auszuführen, und kann dies sogar schaffen schwieriger, diese Ziele zu erreichen.
DMGregory
@DMGregory Ich habe nur gesagt, dass das manuelle Begrenzen der Framerate mit Verzögerungen schrecklich ist und nicht das gewünschte Ergebnis liefert. Sie verwenden also eine Bibliothek mit Framerate-Capping oder vsync, wenn Sie eine feste Framerate benötigen
Xriuk