libgdx Spiel nicht verfügbar

7

Mein Spiel wird auch nach dem Aufruf der dispose () -Methode nicht vollständig beendet. Es lädt einen schwarzen Bildschirm, wenn ich es zum zweiten Mal starte, und funktioniert gut, wenn ich das Spiel manuell beende und neu starte.

Ich erhalte eine Fehlermeldung, buffer not allocated with newUnsafeByteBuffer or already disposedwenn ich versuche, das SpriteBatch-Objekt zu entsorgen. Dies ist, wo ich das Problem vermute. Aber nicht in der Lage, es vollständig zu beheben. Bitte helfen Sie!

Hier ist, wie ich es erstellt habe (ich habe den Beispielcode hier eingefügt, um euch zu zeigen, dass es keine sichtbaren Loopbacks in der Entsorgungsfunktion gibt, bitte korrigiert mich, wenn ich falsch liege) - Im Spielbildschirm,

public void dispose() {
  AssetLoader.dispose();
  render.dispose();
  Gdx.app.exit(); }

Unter der Klasse AssetLoader-

public void dispose(){
  Texture.dispose();
  sound.dispose();
}

Unter Spiel rendern Klasse -

public void dispose(){
  spritebatch.dispose(); //throws an error when I GameScreen.dispose is called
  font.dispose();
  shaperender.dispose();
}

Ich glaube, dass mein Spritebatch nicht entsorgt, was den schwarzen Bildschirm verursacht, aber ich kann keinen Weg finden, ihn erfolgreich zu entsorgen. Jede Hilfe wäre sehr dankbar.

Ja
quelle
Sprechen Sie über Android? libgdx ist plattformübergreifend, das wäre also eine nette Info :-) Ich erwarte Android: Versuchen Sie Folgendes: Starten Sie Ihr Spiel und drücken Sie die Home-Taste des Geräts. Das Spiel wird NICHT geschlossen - es wird ersetzt. Wenn Sie es erneut starten, wird es wieder aufgenommen und nicht neu gestartet. Möglicherweise haben Sie Texturen verloren - hängt davon ab, wie Sie sie implementiert haben. Ich kann mich im Moment nicht genau erinnern, aber Sie müssen sich um diese Situation kümmern. Normalerweise entscheidet Android, wann eine App wirklich entladen werden soll, nicht der Entwickler. Sie müssen sich also trotzdem um einen Lebenslauf kümmern (z. B. eingehender Anruf usw.).
reiti.net
Verwenden Sie tatsächlich "Texture" .dispose (); oder die <nameOfYourTexture (s)>. dispose (); ?
Wes

Antworten:

4

Der Hauptteil der dispose()Methode ist nicht der richtige Ort, um die Gdx.app.exit()Methode aufzurufen . Wenn Sie den letzteren aufrufen, wird der Anruf des ersteren aufgerufen, sodass Sie dispose()Ihre Objekte zum zweiten Mal aufrufen . Tipp: Lesen Sie das Javadoc der Gdx.app.exit()Methode, um genau zu sehen, was sie tut.

Was Sie tun sollten, ist:

  1. Entfernen Sie den Gdx.app.exit()Aufruf von Ihrer dispose()Methode.
  2. Sie haben eine hide()Methode, die aufgerufen wird, wenn Ihre App "versteckt" wird, wenn Sie die Home-Taste drücken, einen eingehenden Anruf erhalten usw. Rufen Sie hier die Dispose-Methode an.
  3. Rufen Sie zum Gdx.app.exit()Beispiel den Hörer einer Schaltfläche an, die für das Beenden des Spiels verantwortlich ist, oder fangen Sie den Druck auf die Zurück-Schaltfläche in Android ab und verwenden Sie ihn dort.

Auf diese Weise stellen Sie sicher, dass alle Ihre Ressourcen ordnungsgemäß entsorgt werden und dass Sie nicht versuchen, etwas ein zweites Mal zu entsorgen.

Hoffe das hilft.

VictorB
quelle
0

Ja, Sie können Ihren gesamten Code Ihrer Entsorgung in der Hide-Methode schreiben. Wenn das Problem dennoch auftritt, können Sie Ihre gesamte Entsorgungsarbeit unmittelbar vor dem Laden Ihrer Assets ausführen und den SpriteBatch beim Start auf Null setzen und dann sein Objekt erstellen.

Mögen :

AssetLoader.dispose (); AssetLoader.load ("Pfad der Textur", "Type.class");

und

spriteBatch = null; spriteBatch = new SpriteBatch ();

Sudhir singh
quelle
0

Dies ist ein altes Thema, aber ich hatte das gleiche Problem und fand es schließlich heraus, indem Gdx.app.log("note: ", "dispose called")ich LogCat-Drucke in der Entsorgungsmethode jedes Bildschirms verwendete. Was tatsächlich passiert ist (auf Android):

  1. Drücken Sie die HOME-Taste => Die Methode pause()wird aufgerufen.
  2. Starten Sie die Anwendung erneut und beim Neustart wird die Entsorgungsmethode des letzten Bildschirms aufgerufen, um den Bildschirm zu aktualisieren. Normalerweise sollte es hier keine Probleme geben.

Das Problem tritt (zumindest in meinem Fall) auf, wenn ich die RETURN-Taste drückte und die App erneut startete, was zu einem Absturz führte. Nun passiert dies:

  1. Drücken Sie die RETURN-Taste => Dies ruft die dispose()Hauptmethode auf, NICHT die pause()Methode. Daher wird jede Ressource entsorgt.
  2. Beim Neustart der App wird anschließend versucht, den letzten Bildschirm erneut zu aktualisieren, um ihn zu aktualisieren. Dies wurde jedoch bereits durch Drücken der RETURN-Taste behoben. Hier ist also das Problem: Die Entsorgungsmethode des aktuellen Bildschirms wird zweimal aufgerufen, wenn RETURN gedrückt wird, was zu folgendem Fehler führt : java.lang.IllegalArgumentException: buffer not allocated with newUnsafeByteBuffer or already disposed.

Ich habe dieses Problem gelöst, indem ich mit einem Booleschen Wert überprüft habe, ob der aktuelle Bildschirm bereits angezeigt wurde. Unten ist ein Beispiel (ich verwende eine abstrakte ScreenKlasse und eine ScreenManager, die einen neuen Bildschirm durch Aufrufen der createMethode einer Unterklasse festlegt ):

public class MainScreen extends Screen {

    private boolean disposed;

    @Override
    public void create() {
        disposed = false;
        //rest of your code here
    }

    @Override
    public void dispose() {
        if (disposed == false) {
            //dispose your resources here
            disposed = true;
        }
    }
}

Also nach dem Drücken von RETURN disposedwird auf gesetzt true. Beim Neustart bleibt dies weiterhin der Fall, sodass die Ressourcen nicht zweimal entsorgt werden. Als nächstes wird der Bildschirm zurückgesetzt und ruft createdies automatisch aufdisposed = false

Ich hoffe das hilft jemandem mit einem ähnlichen Problem in der Zukunft :)


quelle
1
Warum nicht einfach verwenden : if(!disposed)?
Ammar Tarajia
0

Durch Aufrufen der Gdx.app.exitFunktion wird die disposeFunktion ApplicationListenerohnehin vom Hauptteil des Spiels aus aufgerufen. Das Aufrufen der Funktion innerhalb der Dispose führt zu einer Rekursion der Funktion, da sie die Gdx.app.exitFunktion innerhalb der aufgerufenen disposeFunktion erreicht, was zu einem Fehler führt, wenn versucht wird, etwas zu entsorgen, das bereits entsorgt wurde.

Ammar Tarajia
quelle