Problem mit Update (GameTime) -Methoden und Pause-Implementierung

7

Ich habe die Pausenfunktion implementiert und sie funktioniert korrekt, da sie den Player-Bildschirm dimmt und das Gameplay nicht mehr aktualisiert.

Das Problem ist, dass GameTime weiter zunimmt, während es angehalten wird. Daher wird meine Methode, die gameTime im Vergleich zu previousSpawnTime überprüft, bevor ein anderer Feind erzeugt wird, durcheinander gebracht. Wenn das Spiel zu lange angehalten wird, fällt auf, dass der nächste Feind viel zu früh zieht.

Hier ist mein Code für das feindliche Update.

private void UpdateEnemies(GameTime gameTime)
    {
        // Spawn a new enemy every 1.5 seconds
        if (gameTime.TotalGameTime - previousSpawnTime > enemySpawnTime)
        {
            previousSpawnTime = gameTime.TotalGameTime;

            // Add an Enemy
            AddEnemy();
        }
...

Ich habe auch andere Methoden, die von gameTime abhängen. Ich habe versucht, die gesamte Pausenzeit zu ermitteln und von der gesamten Spielzeit zu subtrahieren, aber ich kann nicht scheinen, dass sie richtig funktioniert, wenn ich dies auf diese Weise lösen sollte.

Wenn Sie einen anderen Code benötigen, lassen Sie es mich wissen. Vielen Dank.

Adam LaBranche
quelle

Antworten:

8

Anstatt use zu TotalGameTimeverwenden ElapsedGameTimeund die laufende Summe selbst in einer Variablen zu akkumulieren. Wenn Sie das Spiel dann anhalten, müssen Sie nur noch aufhören, der Variablen die verstrichene Zeit hinzuzufügen. Hier ist ein Beispiel:

float spawnTimer = 0.0f;
float timeBetweenSpawns = 1.5f;

private void Update(GameTime gameTime)
{
    // Perform actions that should only happen when the game is not paused
    if(!isPaused)
    {
        // Add time elapsed since previous frame to running timer
        spawnTimer += (float) gameTime.ElapsedGameTime.TotalSeconds;

        // Check if enough time has passed to spawn a new enemy
        if(spawnTimer >= timeBetweenSpawns)
        {
            AddEnemy();

            // Decrement the timer to prepare it for the next spawn
            spawnTimer -= timeBetweenSpawns;
        }
    }

    // Perform any actions that should happen all the time
}
David Gouveia
quelle
3
Das Aufrufen von UpdateEnemies mit einem Delta von 0,0 ist eine schönere Option, mit der Feinde für Neben- oder Geschmacksaktivitäten wie Langeweile auf die Füße tippen können, ohne das Spiel zu beeinträchtigen. Wenn Sie einfach aufhören, Updates aufzurufen, verlieren Sie solche interessanten Optionen.
Patrick Hughes
@PatrickHughes Ja, ich mag die Idee, dass viele Jungs mitten im Kampf auf ihre Füße klopfen und darauf warten, dass du die Pause machst.
MichaelHouse
1
@PatrickHughes Die Art und Weise, wie ich die Pause demonstrierte, war nur illustrativ, da sich die Frage hauptsächlich mit dem Zeitmanagement befasste. Trotzdem würde ich aus zwei Gründen immer noch kein Null-Zeit-Delta übergeben: GameTimeWird vom Framework automatisch berechnet und verwaltet. Wenn Sie also ein Null-Delta übergeben, müssen Sie ein separates GameTimeObjekt instanziieren oder die Signatur ändern, um einen Float zu verwenden. und selbst mit einem Null-Delta würde es die Additions- und Zeitgeberprüfungen unnötig durchführen. Bei Bedarf würde ich einfach einen Teil der Methode in eine Pausenprüfung einschließen, damit die andere Hälfte weiter aktualisiert werden kann.
David Gouveia
2
@PatrickHughes Was Sie beschreiben, ist eindeutig ein Ansichtskonzept. Wenn das Spiel angehalten wird, rendern Sie Modelle mit "gelangweilten" Animationen. Dies sollte in Ihren Draw-Aufrufen behandelt werden, NICHT in Ihren Update-Aufrufen.
Daniel Carlsson
1
@PatrickHughes Ja, es ist ein bisschen seltsam, weshalb ich in all meinen Projekten als erstes oben in meiner Update-Schleife das GameTimeObjekt in einen einfachen Float konvertiere und stattdessen diesen Wert verwende. Ich hatte noch nie die Notwendigkeit, aber es erleichtert Dinge wie die Implementierung von Zeitlupe - skalieren Sie einfach den Wert der verstrichenen Zeit um eine Konstante. Was das Anhalten des Spiels angeht, ist es wohl eher eine Frage der persönlichen Präferenz - ich behandle die Pause lieber wie einen Ein / Aus-Schalter als wie ein Null-Delta, um zeitabhängige Berechnungen explizit zu überspringen, aber beide sind absolut gültige Lösungen :)
David Gouveia