showAndWait is not allowed during animation or layout processing Memory FX

E

eiligerwind

Mitglied
Hallo Forengemeinde, als Hausaufgabe sollte ich ein Memoryspiel derart erweitern, dass zum einem das Spiel beim Aufdecken der letzten Karte nicht sofort beendet wird und zum anderen ausgeben, wer gewonnen hat (Computer oder Spieler)

Der erste Versuch war dies mit einen Alert Dialog (show&wait) vom Typ Information zu lösen... In diesem Fall würde das Programm erst geschlossen werden, wenn ich den Button o.k. drücke. Allerdings scheint sich dies mit dem noch laufenden Timer zum Umdrehen der letzten Karten zu beißen und ich erhalte die Fehlermeldung:

showAndWait is not allowed during animation or layout processing

Also habe ich im Netz etwas gesucht und bin auf eine Alternative gestoßen die ich wie folgt adaptiert habe:
statt show&wait:
private void infoMenschGewinnt() {
        Alert alert = new Alert(AlertType.INFORMATION);
        alert.setTitle("Spiel Ergebnis:");
        alert.setHeaderText("Resultat:");
        alert.setContentText("Herzlichen Glückwunsch Du hast Gewonnen !! ");
 
        alert.setOnHidden(evt -> Platform.exit());

        alert.show();
    }
    
    private void infoComputerGewinnt() {
        Alert alert = new Alert(Alert.AlertType.INFORMATION);
        alert.setTitle("Spiel Ergebnis:");
        alert.setHeaderText("Resultat:");
        alert.setContentText("Diesmal hat der Computer gewonnen! Click OK to exit.");

        alert.setOnHidden(evt -> Platform.exit());

        alert.show();
        }

Das funktioniert auch, sofern ich als Spieler die letzten Karten aufdecke einwandfrei. Deckt aber der Computer die letzten Karten auf (egal bei welcher Gewinnkonstellation) wird zwar der Dialog angezeigt, aber sobald ich auf "o.K." drücke reagiert das Spiel nicht mehr (keine Rückmeldung). Von Eclipse wird keine Fehlermeldung angezeigt.

als Ergänzung noch der Code für den Computerzug:
Computerzug:
private void computerZug() {
        int kartenZaehler = 0;
        int zufall = 0;
        boolean treffer = false;
        //zur Steuerung über die Spielstärke
        if ((int)(Math.random() * spielstaerke) == 0) {
            //erst einmal nach einem Paar suchen
            //dazu durchsuchen wir das Array gemerkteKarten, bis wir in beiden Dimensionen
            //einen Wert finden
            while ((kartenZaehler < 21) && (treffer == false)) {
                //gibt es in beiden Dimensionen einen Wert größer oder gleich 0?
                if ((gemerkteKarten[0][kartenZaehler] >=0) &&  (gemerkteKarten[1][kartenZaehler] >=0)) {
                    //dann haben wir ein Paar
                    treffer = true;
                    //die Vorderseite der Karte zeigen
                    karten[gemerkteKarten[0][kartenZaehler]].vorderseiteZeigen();
                    //und dann die Karte öffnen
                    karteOeffnen(karten[gemerkteKarten[0][kartenZaehler]]);
                    //die zweite Karte auch
                    karten[gemerkteKarten[1][kartenZaehler]].vorderseiteZeigen();
                    karteOeffnen(karten[gemerkteKarten[1][kartenZaehler]]);
                }
                kartenZaehler++;
            }
        }
        //wenn wir kein Paar gefunden haben, drehen wir zufällig zwei Karten um
        if (treffer == false) {
            //solange eine Zufallszahl suchen, bis eine Karte gefunden wird, die noch im Spiel ist
            do {
                zufall = (int)(Math.random() * karten.length);
            } while (karten[zufall].isNochImSpiel() == false);
            //die erste Karte umdrehen
            //die Vorderseite der Karte zeigen
            karten[zufall].vorderseiteZeigen();
            //und dann die Karte öffnen
            karteOeffnen(karten[zufall]);

            //für die zweite Karte müssen wir außerdem prüfen, ob sie nicht gerade angezeigt wird
            do {
                zufall = (int)(Math.random() * karten.length);
            } while ((karten[zufall].isNochImSpiel() == false) || (karten[zufall].isUmgedreht() == true));
            //und die zweite Karte umdrehen
            karten[zufall].vorderseiteZeigen();
            karteOeffnen(karten[zufall]);
        }
    }

Bin ein Anfänger :) daher tue ich mich mit der Fehlersuche recht schwer, zumal Eclipse Codeseitig nicht meckert. Ich hoffe jemand hat eine Idee, oder ein Alternative hinsichtlich der Anzeige des Gewinners.

vielen Dank im voraus und viele Grüße
 
E

eiligerwind

Mitglied
Habe heute Morgen noch mal etwas rumprobiert... und denke ich weiß, wo das Problem liegt. Allerdings führt mein Lösungsansatz zu einer neuen Auffälligkeit :(

Paar prüfen und Karten aus dem Gedächtnis löschen:
//die Methode prüft, ob ein Paar gefunden wurde
    private void paarPruefen(int kartenID) {
        if (paar[0].getBildID() == paar[1].getBildID()) {
            //die Punkte setzen
            paarGefunden();
            //die Karten aus dem Gedächtnis löschen
            if (menschPunkte+computerPunkte<21) {
            gemerkteKarten[0][kartenID]=-2;
            gemerkteKarten[1][kartenID]=-2;
            }
        }
    }

beim letzten Zug, wenn das letzte Paar gefunden wurde, scheint der Aufruf des Dialogs die Löschung der Karten aus dem Gedächtnis zu verhindern. Daher habe ich die Methode so angepasst , dass beim letzten Paar das Löschen der Karten aus dem Gedächtnis nicht mehr erfolgt ( if menschPunkte+computerPunkte<21)
Das Ergebnis ist, dass das Programm sich zwar nicht mehr aufhängt, allerdings wird der Dialog nun zweimal aufgerufen...und ich finde die schleife nicht :(...zudem wird dadurch dass die Karten nicht aus dem Gedächtnis gelöscht werden, die Punkte des Computers ständig weitergezählt...

falls zur Lösung mehr Code benötigt wird, kann ich den gerne reinstellen :)
VG eiligerwind
 
Zuletzt bearbeitet:
E

eiligerwind

Mitglied
hab es nun selbst rausgefunden... in der Methode karteSchliessen wird überprüft, ob der Computer ein Paar gefunden hat, falls ja wird erneut die Methode computerZug aufgerufen. Das passiert natürlich auch, wenn das letzte Paar gefunden wurde durch den Computer. Und hier scheint es dann zum Problem zu kommen mit der Dialoganzeige und der Beendigung des Programms...🤔... habe nun eine Bedingung eingebaut, dass der computer nur dann wieder ziehen darf, wenn noch nicht alle paare gefunden wurden. Nun klappt es mit der Dialoganzeige. Die Bedingung dass das Gedächtnis nur gelöscht werden soll bis zum vorletzten Paar habe ich wieder rausgenommen, da dies nur zu anderen Problemen (siehe Post zuvor) geführt hat... nun klappt es :)

Methode karteSchliessen:
private void karteSchliessen() {
        if(umgedrehteKarten>0) {
        boolean raus = false;
        //ist es ein Paar?
        if (paar[0].getBildID() == paar[1].getBildID())
            raus = true;
        //wenn es ein Paar war, nehmen wir die Karten aus dem Spiel
        //sonst drehen wir sie nur wieder um
        paar[0].rueckseiteZeigen(raus);
        paar[1].rueckseiteZeigen(raus);
        //es ist keine Karte mehr geöffnet
        umgedrehteKarten = 0;
        //hat der Spieler kein Paar gefunden?
        if (raus == false)
            //dann wird der Spieler gewechselt
            spielerWechseln();
        else
            //hat der Computer ein Paar gefunden?
            //dann ist er noch einmal an der Reihe
            if ((spieler == 1)&&(computerPunkte+menschPunkte<21))
                computerZug();}
        else spieler=0;
    }
 

Ähnliche Java Themen

Anzeige


Oben