Hallo,
ich habe die folgende Aufgabe bekommen.
...
Bauen Sie eine „Schummel“-Funktion in das Memory-Spiel ein. Ergänzen Sie dazu eine Schaltfläche Alles aufdecken. Beim Anklicken der Schaltfläche sollen alle noch nicht aufgedeckten Karten für eine bestimmte Zeit angezeigt und danach automatisch wieder umgedreht werden.
Sorgen Sie dafür, dass die „Schummel“-Funktion nur dann aufgerufen werden kann, wenn gerade der Mensch am Zug ist und wenn keine andere Karte angezeigt wird. Dazu können Sie zum Beispiel die Schaltfläche zum Starten der „Schummel“-Funktion je nach Spielzustand aktivieren beziehungsweise deaktivieren.
Die Lösung ist nicht allzu schwierig, wenn Sie den „richtigen Dreh“ finden. Denken Sie bitte daran, dass Sie unter Umständen das Fenster für die Anwendung ein wenig vergrößern müssen, damit die neue Schaltfläche nach dem Einfügen auch zu sehen ist.
...
Ich habe es soweit geschafft das die Karten sich für 2 Sekunden zeigen und dann wieder umdrehen.
Jedoch bekomme ich es nicht hin das dies über einem Button funktioniert.
Bei Klasse "MemoryFeld" Zeile 104 taucht die Fehlermeldung auf (jetzt auskommentiert) und ich möchte das die Methode von "startschummler()" bei der Klasse "MemoryKarte" Zeile 96 gestartet wird, sobald der Button angeklickt wird.
Weiß jemand weiter, ich nämlich nicht
ich habe die folgende Aufgabe bekommen.
...
Bauen Sie eine „Schummel“-Funktion in das Memory-Spiel ein. Ergänzen Sie dazu eine Schaltfläche Alles aufdecken. Beim Anklicken der Schaltfläche sollen alle noch nicht aufgedeckten Karten für eine bestimmte Zeit angezeigt und danach automatisch wieder umgedreht werden.
Sorgen Sie dafür, dass die „Schummel“-Funktion nur dann aufgerufen werden kann, wenn gerade der Mensch am Zug ist und wenn keine andere Karte angezeigt wird. Dazu können Sie zum Beispiel die Schaltfläche zum Starten der „Schummel“-Funktion je nach Spielzustand aktivieren beziehungsweise deaktivieren.
Die Lösung ist nicht allzu schwierig, wenn Sie den „richtigen Dreh“ finden. Denken Sie bitte daran, dass Sie unter Umständen das Fenster für die Anwendung ein wenig vergrößern müssen, damit die neue Schaltfläche nach dem Einfügen auch zu sehen ist.
...
Ich habe es soweit geschafft das die Karten sich für 2 Sekunden zeigen und dann wieder umdrehen.
Jedoch bekomme ich es nicht hin das dies über einem Button funktioniert.
Bei Klasse "MemoryFeld" Zeile 104 taucht die Fehlermeldung auf (jetzt auskommentiert) und ich möchte das die Methode von "startschummler()" bei der Klasse "MemoryKarte" Zeile 96 gestartet wird, sobald der Button angeklickt wird.
Weiß jemand weiter, ich nämlich nicht
Java:
package einsendeaufgaben_JAVA13C;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.layout.FlowPane;
import javafx.stage.Stage;
public class MemoryFX extends Application{
@Override
public void start(Stage meineStage) throws Exception {
FlowPane rootNode = new MemoryFeld().initGUI(new FlowPane());//den obersten Knoten erzeugen, hier verwenden wir ein FlowPane, erzeugt wird die Oberfläche über eine eigene Methode in der Klasse MemoryFeld
//die Szene erzeugen
//an den Konstruktor werden der oberste Knoten und die Größe übergeben
Scene meineScene = new Scene(rootNode, 480, 600);//die Größe für Aufgabe 1 & Aufgabe 2 angepasst
meineStage.setTitle("Memory");//den Titel über stage setzen
meineStage.setScene(meineScene);//die Szene setzen
meineStage.setResizable(false);//Größenänderungen verhindern
meineStage.show();//und anzeigen
}
public static void main(String[] args) {
launch(args);//der Start
}
}
Java:
package einsendeaufgaben_JAVA13C;
//für die Klassen Arrays und Collections
import java.util.Arrays;
import java.util.Collections;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javafx.scene.control.Button;
import javafx.animation.KeyFrame;
import javafx.animation.Timeline;
import javafx.application.Platform;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.control.Label;
import javafx.scene.layout.FlowPane;
import javafx.scene.layout.GridPane;
import javafx.util.Duration;
public class MemoryFeld extends JFrame {
private static final long serialVersionUID = -6518774972878710759L;
/**
* innere Klasse für den Eventhandler des Timer
* @author silve
*
*/
class TimerHandler implements EventHandler<ActionEvent> {
@Override
/**
* Methode ruft die Methode karteSchliessen() auf
*/
public void handle(ActionEvent arg0) {
karteSchliessen();
}
}
private MemoryKarte[] karten;//das Array für die Karten
//das Array für die Namen der Grafiken
private String[] bilder = {"grafiken/apfel.jpg", "grafiken/birne.jpg", "grafiken/blume.jpg", "grafiken/blume2.jpg",
"grafiken/ente.jpg", "grafiken/fisch.jpg", "grafiken/fuchs.jpg", "grafiken/igel.jpg",
"grafiken/kaenguruh.jpg", "grafiken/katze.jpg", "grafiken/kuh.jpg", "grafiken/maus1.jpg",
"grafiken/maus2.jpg", "grafiken/maus3.jpg", "grafiken/melone.jpg", "grafiken/pilz.jpg",
"grafiken/ronny.jpg", "grafiken/schmetterling.jpg","grafiken/sonne.jpg",
"grafiken/wolke.jpg", "grafiken/maus4.jpg"};
private int menschPunkte, computerPunkte;//für die Punkte
private Label menschPunkteLabel, computerPunkteLabel, esziehtLabel;//zwei Labels für die Punkte
private String anzeige1, anzeige2;//Aufgabe 2 für die Anzeige wer zieht
private int umgedrehteKarten;//wie viele Karten sind aktuell umgedreht?
private MemoryKarte[] paar;//für das aktuell umdrehte Paar
private int spieler;//für den aktuellen Spieler
private int[][] gemerkteKarten;//das "Gedächtnis" für den Computer, er speichert hier wo das Gegenstück liegt
private int spielstaerke;//für die Spielstärke
private Timeline timer;//für den Timer
//der Konstruktor
public MemoryFeld() {
karten = new MemoryKarte[42];//das Array für die Karten erstellen, insgesamt 42 Stück
paar = new MemoryKarte[2];//für das Paar
gemerkteKarten = new int[2][21];//für das Gedächtnis, es speichert für jede Karte paarweise die Position im Spielfeld
anzeige1 = "Der Mensch"; //Aufgabe 2, für die Bezeichnung wer gerade zieht
anzeige2 = "Der Computer"; //Aufgabe 2, für die Bezeichnung wer gerade zieht
//keiner hat zu Beginn einen Punkt
menschPunkte = 0;
computerPunkte = 0;
umgedrehteKarten = 0;//es ist keine Karte umgedreht
spieler = 0;//der Mensch fängt an
spielstaerke = 0;//die Spielstärke ist 10
//es gibt keine gemerkten Karten
for (int aussen = 0; aussen < 2; aussen++)
for (int innen = 0; innen < 21; innen++)
gemerkteKarten[aussen][innen] = -1;
}
/**
* Methode erstellt die Oberfläche und zeichnet die Karten über eine eigene Methode, übergeben wird ein FlowPane
*/
public FlowPane initGUI(FlowPane feld) {
kartenZeichnen(feld);//für die Ausgaben
menschPunkteLabel = new Label();
computerPunkteLabel = new Label();
esziehtLabel = new Label();//Aufgabe 2
menschPunkteLabel.setText(Integer.toString(menschPunkte));
computerPunkteLabel.setText(Integer.toString(computerPunkte));
Button buttonschummeln = new Button("schummeln");//Aufgabe 3
//hier komme ich nicht weiter, die Aktivierung über den Button bekomme ich nicht hin
//buttonschummeln.setOnAction(new MemoryKarte.startschummler);//Aufgabe 3
GridPane tempGrid = new GridPane();//in vier Spalten anzeigen
tempGrid.add(new Label("Mensch: "), 0 , 0 );//und einfügen, dabei werden die Koordinaten angegeben
tempGrid.add(menschPunkteLabel, 1, 0);
tempGrid.add(new Label("Computer: "), 0, 1);
tempGrid.add(computerPunkteLabel, 1, 1);
tempGrid.add(new Label("Es zieht: "), 0, 2 ); //Aufgabe 2
tempGrid.add(esziehtLabel, 1, 2);//Aufgabe 2
tempGrid.add(buttonschummeln, 0, 3);//Aufgabe 3
feld.getChildren().add(tempGrid);
return feld;
}
private void kartenZeichnen(FlowPane feld) {//das eigentliche Spielfeld erstellen
int count = 0;
for (int i = 0; i <= 41; i++) {
karten[i] = new MemoryKarte(bilder[count], count, this);//eine neue Karte erzeugen
if ((i + 1) % 2 == 0)//bei jeder zweiten Karte kommt auch ein neues Bild
count++;
}
Collections.shuffle(Arrays.asList(karten));//die Karten werden gemischt
for (int i = 0; i <= 41; i++) {//und ins Spielfeld gesetzt
feld.getChildren().add(karten[i]);
karten[i].setBildPos(i);//die Position der Karte setzen
}
}
/**
* Methode übernimmt die wesentliche Steuerung des Spiels
*/
public void karteOeffnen(MemoryKarte karte) {//Sie wird beim Anklicken einer Karte ausgeführt
int kartenID, kartenPos;//zum Zwischenspeichern der ID und der Position
esziehtLabel.setText((anzeige1));//Aufgabe 2, wenn der Mensch eine Karte anklickt wird angezeigt das der Mensch zieht
paar[umgedrehteKarten]=karte;//die Karten zwischenspeichern
kartenID = karte.getBildID();//die ID und die Position beschaffen
kartenPos = karte.getBildPos();
if ((gemerkteKarten[0][kartenID] == -1)) //die Karte in das Gedächtnis des Computers eintragen, aber nur dann, wenn es noch keinen Eintrag an der entsprechenden Stelle gibt
gemerkteKarten[0][kartenID] = kartenPos;
else
if (gemerkteKarten[0][kartenID] != kartenPos) //wenn es schon einen Eintrag gibt und der nicht mit der aktuellen Position übereinstimmt, dann haben wir die, zweite Karte gefunden, die wird dann in die zweite Dimension eingetragen
gemerkteKarten[1][kartenID] = kartenPos;
umgedrehteKarten++;//umgedrehte Karten erhöhen
if (umgedrehteKarten == 2) {//sind 2 Karten umgedreht worden?
paarPruefen(kartenID);//dann prüfen wir, ob es ein Paar ist
timer = new Timeline(new KeyFrame(Duration.millis(2000), new TimerHandler()));//den Timer erzeugen
timer.play();//und starten
}
if (computerPunkte + menschPunkte == 21) {//haben wir zusammen 21 Paare, dann ist das Spiel vorbei
if (menschPunkte > computerPunkte) {//Aufgabe 1
JOptionPane.showMessageDialog(this, "Der Mensch hat Gewonnen");
}
else {
JOptionPane.showMessageDialog(this, "Der Computer hat Gewonnen");
}
Platform.exit();
}
}
/**
* Methode dreht die Karten wieder auf die Rückseite, bzw. nimmt sie aus dem Spiel
*/
private void karteSchliessen() {
boolean raus = false;
if (paar[0].getBildID() == paar[1].getBildID()) //ist es ein Paar?
raus = true;
paar[0].rueckseiteZeigen(raus);//wenn es ein Paar war, nehmen wir die Karten aus dem Spiel, sonst drehen wir sie nur wieder um
paar[1].rueckseiteZeigen(raus);
umgedrehteKarten = 0;//es ist keine Karte mehr geöffnet
if (raus == false) { //hat der Spieler kein Paar gefunden?
spielerWechseln();//dann wird der Spieler gewechselt
}
else
if (spieler == 1)//hat der Computer ein Paar gefunden?, dann ist er noch einmal an der Reihe
computerZug();
}
/**
* Methode prüft, ob ein Paar gefunden wurde
* @param kartenID
*/
private void paarPruefen(int kartenID) {
if (paar[0].getBildID() == paar[1].getBildID()) {
paarGefunden();//die Punkte setzen
gemerkteKarten[0][kartenID]=-2;//die Karten aus dem Gedächtnis löschen
gemerkteKarten[1][kartenID]=-2;
}
}
/**
* Methode setzt die Punkte, wenn ein Paar gefunden wurde
*/
private void paarGefunden() {
if (spieler == 0) {//spielt gerade der Mensch?
menschPunkte++;
menschPunkteLabel.setText(Integer.toString(menschPunkte));
}
else {
computerPunkte++;
computerPunkteLabel.setText(Integer.toString(computerPunkte));
}
}
/**
* Methode wechselt den Spieler
*/
private void spielerWechseln() {
if (spieler == 0) {//wenn der Mensch an der Reihe war, kommt jetzt der Computer
spieler = 1;
computerZug();
}
else
spieler = 0;
esziehtLabel.setText(anzeige2);//Aufgabe 2
}
/**
* Methode setzt die Computerzüge um
*/
private void computerZug() {
int kartenZaehler = 0;
int zufall = 0;
boolean treffer = false;
if ((int)(Math.random() * spielstaerke) == 0) {//zur Steuerung über die Spielstärke
while ((kartenZaehler < 21) && (treffer == false)) {//erst einmal nach einem Paar suchen, dazu durchsuchen wir das Array gemerkteKarten, bis wir in beiden Dimensionen, einen Wert finden
if ((gemerkteKarten[0][kartenZaehler] >=0) && (gemerkteKarten[1][kartenZaehler] >=0)) {//gibt es in beiden Dimensionen einen Wert größer oder gleich 0?
treffer = true;//dann haben wir ein Paar
karten[gemerkteKarten[0][kartenZaehler]].vorderseiteZeigen();//die Vorderseite der Karte zeigen
karteOeffnen(karten[gemerkteKarten[0][kartenZaehler]]);//und dann die Karte öffnen
karten[gemerkteKarten[1][kartenZaehler]].vorderseiteZeigen();//die zweite Karte auch
karteOeffnen(karten[gemerkteKarten[1][kartenZaehler]]);
}
kartenZaehler++;
}
}
if (treffer == false) {//wenn wir kein Paar gefunden haben, drehen wir zufällig zwei Karten um
do {//solange eine Zufallszahl suchen, bis eine Karte gefunden wird, die noch im Spiel ist
zufall = (int)(Math.random() * karten.length);
} while (karten[zufall].isNochImSpiel() == false);
karten[zufall].vorderseiteZeigen();//die erste Karte umdrehen, die Vorderseite der Karte zeigen
karteOeffnen(karten[zufall]);//und dann die Karte öffnen
do {//für die zweite Karte müssen wir außerdem prüfen, ob sie nicht gerade angezeigt wird
zufall = (int)(Math.random() * karten.length);
} while ((karten[zufall].isNochImSpiel() == false) || (karten[zufall].isUmgedreht() == true));
karten[zufall].vorderseiteZeigen();//und die zweite Karte umdrehen
karteOeffnen(karten[zufall]);
esziehtLabel.setText(anzeige2);//Aufgabe 2
}
}
/**
* Methode liefert, ob Züge des Menschen erlaubt sind
* @return
*/
public boolean zugErlaubt() {//die Rückgabe ist false, wenn gerade der Computer zieht, oder wenn schon zwei Karten umgedreht sind sonst ist die Rückgabe true
boolean erlaubt = true;
if (spieler == 1)//zieht der Computer?
erlaubt = false;
if (umgedrehteKarten == 2)//sind schon zwei Karten umdreht?
erlaubt = false;
return erlaubt;
}
}
Java:
package einsendeaufgaben_JAVA13C;
import javafx.event.EventHandler;
import javafx.scene.control.Button;
import javafx.scene.image.ImageView;
import javafx.util.Duration;
import javafx.animation.KeyFrame;
import javafx.animation.Timeline;
import javafx.event.ActionEvent;
/**
* Klasse für eine Karte des Memory-Spiels, die erbst von Button
*/
public class MemoryKarte extends Button {
private int bildID;//die Instanzvariablen, eine eindeutige ID zur Identifizierung des Bildes
private ImageView bildVorne, bildHinten;//für die Vorder- und Rückseite
private int bildPos;//wo liegt die Karte im Spielfeld
private boolean umgedreht;//ist die Karte umgedreht?
private boolean nochImSpiel;//ist die Karte noch im Spiel?
private MemoryFeld spielfeld;//das Spielfeld für die Karte
private Timeline timer;//für den Timer, Aufgabe 3
/**
* die innere Klasse für den Eventhandler der Karte
*/
class KartenHandler implements EventHandler<ActionEvent>{
@Override
public void handle(ActionEvent arg0) {
if ((nochImSpiel == false) || (spielfeld.zugErlaubt() == false))//ist die Karte überhaupt noch im Spiel und sind Züge erlaubt?
return;
if (umgedreht == false) {//wenn die Rückseite zu sehen ist, die Vorderseite anzeigen
vorderseiteZeigen();
spielfeld.karteOeffnen(MemoryKarte.this);//die Methode karteOeffnen() im Spielfeld aufrufen, übergeben wird dabei die Karte also die this-Referenz der äußeren Klasse
}
}
}
//der Konstruktor er setzt die Bilder
public MemoryKarte(String vorne, int bildID, MemoryFeld spielfeld) {
bildVorne = new ImageView(vorne);//die Vorderseite, der Dateiname des Bildes wird an den Konstruktor übergeben
bildHinten = new ImageView("grafiken/back.jpg");//die Rückseite, sie wird fest gesetzt
setGraphic(bildHinten);
startschummler();
this.bildID = bildID;//die Bild-ID
umgedreht = false;//die Karte ist erst einmal umgedreht und noch im Feld
nochImSpiel = true;
this.spielfeld = spielfeld;//mit dem Spielfeld verbinden
setOnAction(new KartenHandler());//die Action setzen
}
public void vorderseiteZeigen() {//Methode zeigt die Vorderseite der Karte an
setGraphic(bildVorne);
umgedreht = true;
}
public void rueckseiteZeigen(boolean rausnehmen) {//Methode zeigt die Rückseite der Karte an
if (rausnehmen == true) {//soll die Karten komplett aus dem Spiel genommen werden?
setGraphic(new ImageView("grafiken/aufgedeckt.jpg"));//das Bild aufgedeckt zeigen und die Karte aus dem Spiel nehmen
nochImSpiel = false;
}
else {
setGraphic(bildHinten);//sonst nur die Rückseite zeigen
umgedreht = false;
}
}
public int getBildID() {//die Methode liefert die Bild-ID einer Karte
return bildID;
}
public int getBildPos() {//die Methode liefert die Position einer Karte
return bildPos;
}
public void setBildPos(int bildPos) {//die Methode setzt die Position einer Karte
this.bildPos = bildPos;
}
public boolean isUmgedreht() {//die Methode liefert den Wert der Variablen umgedreht
return umgedreht;
}
public boolean isNochImSpiel() {//die Methode liefert den Wert der Variablen nochImSpiel
return nochImSpiel;
}
//Made by Dennis Aufgabe 3
public void startschummler() {//Methode um den Timer zu starten für Aufgabe 3
timer = new Timeline(new KeyFrame(Duration.millis(1000), new TimerSchummlerPhase1()));
timer.play();//und starten
}
//Made by Dennis Aufgabe 3
class TimerSchummlerPhase1 implements EventHandler<ActionEvent> {
public void handle(ActionEvent arg0) {//hier werden alle Karten für 2 Sekunden angezeigt
vorderseiteZeigen();
timer = new Timeline(new KeyFrame(Duration.millis(2000), new TimerSchummlerPhase2()));//den Timer erzeugen
timer.play();//und starten
}
}
class TimerSchummlerPhase2 implements EventHandler<ActionEvent> {
public void handle(ActionEvent arg0) {//nach den 2 Sekunden wird wieder Rückseite angeseigt
rueckseiteZeigen(false);
}
}
}