Memory-Spiel mit Schummelfunktion
-
Hallo, ich programmiere gerade ein Memory-Spiel mit einer Schummelfunktion, über einen Button, mit einen Timer. Es funktioniert auch soweit alles wunderbar. Nur nach endlichen Zügen und gefunden Pärchen, wie das immer wieder benutzen der Schummelfunktion. Gibt mir die Methode getUmdrehen() true zurück und läuft in den Else zweig wo der Timer gestoppt wird. Ich weiß echt nicht woran es liegen könnte, vielleicht habt Ihr ja eine Idee?
Über hilfe wäre ich sehr dankbar.
void Memoryspiel::ButtonfuerSchummeln() { int zeile = 0; int spalte = 0; if (zugErlaubt() == true) { if ((karten[(zeile * 7) + spalte]->getUmgedreht() == false)) { //QMessageBox::information(this, "Spielende", "false_1,"); for (int zeile = 0; zeile < 7; zeile++) for (int spalte = 0; spalte < 6; spalte++) karten[(spalte * 7) + zeile]->umdrehen(); timerschumeln->start(1000); } else { // QMessageBox::information(this, "Spielende", "true_1,"); for (int zeile = 0; zeile < 7; zeile++) for (int spalte = 0; spalte < 6; spalte++) karten[(spalte * 7) + zeile]->umdrehen(); timerschumeln->stop(); } }
-
Du fragst ja immer die Karte mit dem Index
0
ab - was passiert denn ingetUmgedreht()
, wenn diese Karte schon entfernt wurde?
Du könntest z.B. abfragen, ob derTimer
noch nicht gestartet wurde.PS: Statt der Literale (z.B.
6
,7
) solltest du dafür benannte Konstanten anlegen und verwenden.
Und der Code bei denfor
-Schleifen sollte auch besser eingerückt sein (diese solltest du außerdem in eine eigene FunktionAlleKartenUmdrehen
auslagern).
-
In getUmgedreht() wird mir nur der Status von umgedreht zugeliefert ob er true oder false ist.
//den Status von umgedreht liefern bool Memorykarte::getUmgedreht() { return umgedreht; }
und in umgedreht() wird die Karte gedreht
void Memorykarte::umdrehen() { //ist die Karte schon umgedreht? //dann die Rückseite anzeigen, aber nur dann, wenn die Karte noch im Spiel ist if (nochImSpiel == true) { if (umgedreht == true) { setIcon(bildHinten); umgedreht = false; } //sonst die Vorderseite zeigen else { setIcon(bildVorne); umgedreht = true; } } }
-
Na also! Wenn die Karte aber nicht mehr im Spiel ist, dann wird weiterhin der
umgedreht
-Status zurückgeliefert (der jatrue
beim Entfernen der Karte ist).
-
Erstmals danke für den Bemühungen!!!!
Ich verstehe deine Aussage noch nicht so richtig.
Es wird so verhindert wenn die Karte rausgenommen wird das umdrehen() ausgerufen wird.//die Karte aus dem Spiel nehmen void Memorykarte::rausnehmen() { //die Grafik für aufgedeckt zeigen setIcon(QIcon(":/bilder/aufgedeckt.bmp")); nochImSpiel = false; }
-
Was ich jetzt rausgefunden habe ist, das Attribut umgedreht im Konstruktor der Klasse Memorykarte
//der Konstruktor Memorykarte::Memorykarte(QString vorne, int id) { //die Vorderseite //der Dateiname des Bildes wird an den Konstruktor übergeben bildVorne = QIcon(vorne); //die Rückseite ist festgesetzt bildHinten = QIcon(":/bilder/back.bmp"); //die Rückseite wird angezeigt setIcon(bildHinten); //die Karte ist nicht umgedreht umgedreht = false; //die Karte ist noch im Spiel nochImSpiel = true; //die Nummer setzen bildID = id; }
Wechselt auf einmal von false aus true vermutlich durch den Schummelbutton dadurch wird mir über die Methode getUmdreht() nur noch true zurückgeben und er springt nur noch in den else zweig wo der Timer gestoppt wird.
Was ich nicht verstehe der Schummelbutton ist in einer ganz anderen Klasse im Algorithmus des Spiels.
-
@M-W sagte in Memory-Spiel mit Schummelfunktion:
void Memorykarte::rausnehmen()
{
//die Grafik für aufgedeckt zeigen
setIcon(QIcon(":/bilder/aufgedeckt.bmp"));
nochImSpiel = false;
}Was @Th69 sagen wollte: was wenn die Karte zu dem Zeitpunkt wo sie rausgenommen wird
umgedreht == true
hat? Dann bleibt die weiterhin aufumgedreht == true
. Und wenn das mit der ersten Karte passiert, dann bekommst du genau das Verhalten was du beschrieben hast.Jetzt könnte man auf die Idee kommen in
rausnehmen
einfachumgedreht == false
zu setzen. Das würde zum Starten des Timers dann auch funktionieren - aber nicht zum Beenden. Weil du ja inumdrehen
alle Karten überspringst die nicht mehr im Spiel sind.Also mach z.B. eine eigene Variable in der du dir merkst ob der Schummel-Timer gestartet wurde oder nicht.
-
@Th69 sagte in Memory-Spiel mit Schummelfunktion:
Du könntest z.B. abfragen, ob der
Timer
noch nicht gestartet wurde.Dies ginge mit isActive().
-
Hallo, Ihr seit echt spitze danke für die Unterstützung.
Ich versuche gerade das Umdrehen der Bilder nur durch den Timer zu steuern.
Was dazu führt das er aus halb der Anfrage niemals true ist und die Bilder die ganze Zeit Toggeln.//if (karten[(zeile * i) + spalte]->getUmgedreht() == false) if ( timerschumeln->isActive() == false) { timerschumeln->start(1000); for (int zeile = 0; zeile < i; zeile++) for (int spalte = 0; spalte < y; spalte++) karten[(spalte * i) + zeile]->umdrehen(); } else { timerschumeln->stop(); for (int zeile = 0; zeile < i; zeile++) for (int spalte = 0; spalte < y; spalte++) karten[(spalte * i) + zeile]->umdrehen(); }
-
Was machst du denn in der
timeout
-Slot-Funktion?
Und möchtest du nicht eher einen singleShot-Timer (also der nur einmal dietimeout
-Slot-Funktion ausführt)?
-
Ich benutze den Timer als singelShot.
timerschumeln = new QTimer(this); //er soll nur einmal ausgeführt werden timerschumeln->setSingleShot(true);
Bei den Solt bin ich selbst ein bisschen unsicher, ich rufe immer wieder die Methode ButtonfuerSchummeln auf.
void Memoryspiel::timerSchumeln() { //die Karten wieder umdrehen ButtonfuerSchummeln(); }
-
War selber schon am überlegen die Logik für das hochzählen der Karten im Slot zu machen und das umdrehen im ButtonEvent.
-
Wie ich schon schrieb, mache dir eine Funktion
AlleKartenUmdrehen
und rufe diese im Timer auf (bisher aktivierst du ja immer wieder denTimer
neu ;-).PS:
Schummeln
(mit 2 m).
-
Ich glaube ich habe es, erstmal soviel, werden noch ein bisschen Test, man soll ja nicht den Tag vor den Abend loben.
Habe mir eine neue Member Variable in der Klasse erstellt mit 0 initialisiert.
Im Buttonevent starte ich den timer und lasse die Member Variabel über isAktive() mit hochzählen.
Im Slot machen ich alleKarten anzeigen und springe zurück zur Button Methode.Wenn Timer 3mal gestartet ist Stoppe ich in über die Member Variable.
Bis jetzt läuft es sauber
-
Wofür soll denn das "3mal" sein?
-
Wenn ich nur bis 2 zähle werden mir die Bilder nur einmal umgedreht.
So habe ich es jetzt.void Memoryspiel::ButtonfuerSchummeln() { if (zugErlaubt() == true) { timerschummeln->start(1000); if (timerschummeln->isActive() == true){ i++; } if(i==3){ timerschummeln->stop(); i=0; } } }
-
Schmerzen
-
Wieso Schmerzen?
-
Weil das weh tut was du postest.
-
Dann erkläre es mir doch richtig.