Quizspiel Punktezähler


#1
Guten Tag liebe Nutzer,

ich habe es mir zum Ziel gesetzt ein Programm zu entwerfen, welches mir hilft bei einem Quizspiel die Punkte zu zählen. Die Regeln des Spiels lauten wie folgt:

Wird eine Frage richtig beantwortet erhalten die Spieler Punkte entsprechend eines Zählers. Je höher der Zähler, desto mehr Punkte. Anschließend erhöht sich der Zähler um 1.

Wird eine Frage falsch beantwortet verlieren die Spieler alle ihre Punkte und der Zähler wird auf 0 zurückgesetzt.

Die Spieler können jederzeit ihre aktuelle Punktzahl in die Bank geben und sie damit sichern. Dies setzt jedoch den Zähler auf 0 zurück.

Nun wollte ich das ganze benutzerfreundlich grafisch umsetzen, hier ist mein Code:

Java:
public class Quiz {
private int zaehler;
private int bank;
private int punkte;
private Main main;
   
    public Quiz(Main main){
        this.zaehler = 0;
        this.bank = 0;
        this.punkte = 0;
        this.main = main;
    }
   
    public void banken(){
        this.bank += this.punkte;
        this.zaehler = 0;
        main.aktualisieren();
    }
   
    public void richtig(){
       
        switch(this.zaehler){
        case 0: this.punkte += 1; break;
        case 1: this.punkte += 2; break;
        case 2: this.punkte += 4; break;
        case 3: this.punkte += 6; break;
        case 4: this.punkte += 9; break;
        case 5: this.punkte += 12; break;
        case 6: this.punkte += 15; break;
        case 7: this.punkte += 18; break;
        case 8: this.punkte += 21; break;
        case 9: this.punkte += 25; break;
        default:
        }
       
        if(this.zaehler < 9){
            this.zaehler ++;
        }
       
        main.aktualisieren();
    }
   
    public void falsch(){
        this.punkte = 0;
        this.zaehler = 0;
        main.aktualisieren();
    }
   
    public int getPunkte(){
        return this.punkte;
    }
   
    public int getBank(){
        return this.bank;
    }
}
Java:
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JLabel;

public class Main {
    private Quiz quiz;
    private JLabel punkte;
    private JLabel bank;
    private JFrame frame;
    private JButton richtig;
    private JButton falsch;
    private JButton banken;

    public static void main(String[] args) {
        new Main();
    }
   
    public Main(){
        quiz = new Quiz(this);
        //Frame
        frame = new JFrame("Quizspiel");
        frame.setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
        frame.setSize(500, 350);
       
        //Grundcontainer für den Hintergrund
        JPanel rootpanel = new JPanel(new java.awt.BorderLayout());
       
        //Container für die Knöpfe
        JPanel buttonpanel = new JPanel(new java.awt.FlowLayout());
       
        //Knopf richtig
        this.richtig = new JButton("Richtig");
        richtig.addActionListener(new java.awt.event.ActionListener(){
            public void actionPerformed(java.awt.event.ActionEvent e){
                quiz.richtig();
            }
        });
       
        buttonpanel.add(richtig);
       
        //Knopf falsch
        this.falsch = new JButton("Falsch");
        richtig.addActionListener(new java.awt.event.ActionListener(){
            public void actionPerformed(java.awt.event.ActionEvent e){
                quiz.falsch();
            }
        });
       
        buttonpanel.add(falsch);
       
        //Knopf bank
        this.banken = new JButton("Bank");
        richtig.addActionListener(new java.awt.event.ActionListener(){
            public void actionPerformed(java.awt.event.ActionEvent e){
                quiz.banken();
            }
        });
       
        buttonpanel.add(banken);
       
        rootpanel.add(buttonpanel, java.awt.BorderLayout.NORTH);
       
       
        JPanel labelpanel = new JPanel(new java.awt.FlowLayout());
        punkte = new JLabel("Punkte: " + quiz.getPunkte());
        bank = new JLabel("Bank: " + quiz.getBank());
       
        labelpanel.add(punkte);
        labelpanel.add(bank);
       
        rootpanel.add(labelpanel, java.awt.BorderLayout.CENTER);
       
        frame.add(rootpanel);
        frame.setVisible(true);
    }
   
    public void aktualisieren(){
        punkte.setText("Punkte: " + quiz.getPunkte());
        bank.setText("Bank: " + quiz.getBank());
        frame.validate();
        frame.repaint();
    }

}
Mein Problem ist, dass bei Drücken des Knopfes "Richtig" beim ersten mal zwar alles funktioniert, jedoch ab dem zweiten Mal die Punktzahl nicht mehr geändert und jedes mal die Bank um eins erhöht wird. Jedoch kommt im aufgerufenen Code keine einzige Zeile zur Veränderung der Bank vor. Mit dem Debugger konnte ich feststellen, dass sich tatsächlich die Attribute von Quiz ändern, nachdem ActionPerformed vollständig ausgeführt wurde (also nach den gewollten Änderungen des ersten Knopfdrucks erfolgen weitere ungewünschte Änderungen, welche so im Code nicht zu finden sind. Beispiel: nach dem Aufruf der Methode "richtig" waren die Attribute zaehler und punkte wie gewollt 1 und bank 0. Sobald ich allerdings mit F5 aus der Methode herausgesprungen bin und ActionPerformed abgeschlossen habe änderten sich die Attribute zaehler und punkte auf 0 und bank auf 1. Eine solche Änderung ist nirgends in meinem Quellcode vorgesehen!).

Ich hoffe wirklich ihr könnt mir hier weiterhelfen, ich bin mit meinem Latein völlig am Ende...

Vielen Dank für eure Hilfe,
shorty01012
 

melmager

Erfahrenes Mitglied
#2
Die Main Classe wird schon mal falsch erstellt.

Code:
public static void main(String[] args) {
        new Main();
    }
  
    public Main(){
sollte so aussehen:

Code:
public static void main(String[] args) {

quiz = new Quiz();
dann solltest du auch nicht aus der Quiz Classe heraus eine Function von der Main Classe aufrufen.
besser so:

Code:
richtig.addActionListener(new java.awt.event.ActionListener(){
            public void actionPerformed(java.awt.event.ActionEvent e){
                quiz.banken();
                aktualisieren();
            }
        });
 
#3
Hab ich auch alles erst mal so gemacht, funktioniert nur leider nicht. Die Main-Methode ist static, also kann ich in ihr nicht auf das nicht-statische Attribut Quiz zugreifen. Und die Sache mit dem aktualisieren geht auch nicht, denn der new Actionlistener kennt logischerweise die Methode aktualisieren der Main-Klasse nicht. So, wie ich das habe, meckert der compiler wenigstens nicht. Hab mittlerweile herausgefunden, dass wenn ich einen Button drücke die ActionPerformed-Methoden der anderen Buttons auch aufgerufen werden. Weiß jemand, wie ich das verhindern kann?
 
#4
Okay, das Problem war ein simpler Tippfehler aufgrund von Schreibfaulheit x'D
Wenn man den Code für addActionlistener copy und pastet sollte man vielleicht das Objekt noch ändern, das diese aufruft :D