Frage

Ich arbeite an einem kleinen Android-Spiel, das das Zeichnen von Leinwand in einem Arbeitsthread übernimmt.Nachdem das Spiel vorbei ist, sollte dieser Thread mit der nächsten Aktivität beginnen, aber irgendwie scheint der UI-Thread durch das Starten einer neuen Funktion blockiert zu werden.

Das ist die Hauptschleife meines Spiels:

while(true)
    // Perform Ticks until the player makes a mistake
    c = _surfaceHolder.lockCanvas();
    if ((toDraw = rh.performTick()) == null) {
         lose();
         break;
     }
     _surfaceHolder.unlockCanvasAndPost(draw(toDraw,c));
}

Die Funktion performTick() verarbeitet die Spiellogik und gibt zurück null wenn das Spiel endet. draw()übernimmt das Rendern.Beide Funktionen funktionieren einwandfrei - das Problem ist lose(), was nichts weiter tut, als eine neue Aktivität zu starten:

    protected void lose() {
        Handler handler = new Handler(Looper.getMainLooper());
        handler.post(new Runnable() {
            @Override
            public void run() {
                Intent intent = new Intent(_context, MainMenu.class);
                _context.startActivity(intent);
            }
        });
    }

Wenn das Spiel endet, startet die neue Aktivität (Hauptmenü) normal, reagiert jedoch nicht auf Berührungsereignisse.Es gibt keine LogCat-Ausgabe und es tritt keine Ausnahme auf.Noch schlimmer, lose()funktioniert normal, wenn es aufgerufen wird, BEVOR die Hauptschleife beginnt.

Ich arbeite jetzt schon seit Tagen daran.Ich habe versucht, die Aktivität direkt vom Arbeitsthread aus zu starten (ohne a Handler In lose()) und stundenlang im Internet gesucht - nichts hilft.Es scheint, als wäre der UI-Thread irgendwie blockiert oder in einer Endlosschleife gefangen, und ich habe keine Ahnung, wie ich das beheben kann.

Alles wird auf einem Nexus 4-Gerät debuggt.

Übrigens: MainMenu.onCreate() Funktioniert normal, wenn es anders gestartet wird.

Bitte helfen Sie, MA3O

War es hilfreich?

Lösung

Sie entsperren die Leinwand nicht, wenn die if-Anweisung wahr ist.„Pause“ holt Sie aus der Zwischenzeit heraus und lässt die Leinwand gesperrt.

while(true)
    // Perform Ticks until the player makes a mistake
    c = _surfaceHolder.lockCanvas();
    if ((toDraw = rh.performTick()) == null) {
         lose();
         break;
     }

     // this line won't be executed whether the if statement above is true
     _surfaceHolder.unlockCanvasAndPost(draw(toDraw,c));
}

Sie sollten auch innerhalb der if-Anweisung entsperren (vor oder nach lose()).

Andere Tipps

Stattdessen wenn While(true) du könntest haben While(myVar) Wo myVar ist ein boolescher Wert, der wahr ist, während das Spiel ausgeführt werden soll, und beim Aufruf auf falsch gesetzt wird lose() In Ihrem Fall haben Sie weiter gezeichnet, obwohl es nicht nötig war.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top