Pufferproblem bei sich wiederholenden MouseEvents

JonnyAd

Mitglied
Hallo,

ich habe ein kleines Konzentrationsspiel in Form eines Applets programmiert, welches online gespielt werden kann. Eine Anbindung an eine Datenbank ist vorhanden. Hier werden User spezifische Parameter gespeichert und zudem ist eine Highscoreaufstellung möglich. Aufgabe des Spiels ist es, die Zahlen von 1 bis n anzuklicken. Es wird also eine Matrix gezeigt mit n Label Feldern. In jedem Label steht eine Zahl. Drückt man auf einen Start Button, so wird nach einem Zufallsprinzip gemischt, eine Stopuhr gestartet und anschließend sollen die Zahlen so schnell wie möglich in der richtigen Reihenfolge angeklickt werden. Klickt man die richtige Zahl an, so färbt sich die Hintergrundfarbe des Labels kurz grün und ein angenehmer Sound (im .wav Format) von ca. 0,3 Sekunden wird abgespielt. Bei einer falschen Zahl: Farbe rot und ein entsprechend unangenehmer Sound.

Problem der ganzen Geschichte ist jedoch, dass gelegentlich der Sound bei jedem Klick zweimal hintereinander abgespielt wird. Dieser Fehler zieht sich dann die gesamte Spielzeit durch, zur Abschaffung muss das Spiel also noch einmal neu gestartet werden. Zudem passiert es gelegentlich, dass bei Klick auf ein Label keine Färbung erfolgt, weil der PC rechen- oder speichertechnisch scheinbar nicht hinterherkommt. Man klickt also schon das nächste und übernächste Label an, aber es passiert nichts. Erst nach wenigen Sekunden färben sich dann die entsprechenden Labels kurz.

Hier der relevante Code:

Java:
private class zjbtMouseListener extends  MouseAdapter {
 public void mousePressed(MouseEvent e) {
     labeldummy = (JLabel)(e.getSource());
     if (labeldummy.isEnabled()) {
        if (Integer.valueOf(labeldummy.getText()) == (NumbertoFind)) {
            NumbertoFind++;
            new Thread(new TaskPressedRight(a[1][Integer.valueOf(labeldummy.getText())])).start();
        }
        else {
            new Thread(new TaskPressedWrong(a[1][Integer.valueOf(labeldummy.getText())])).start();
        }

     }
}
}

private class TaskPressedWrong implements Runnable {
    private int indexlabeldummy2;

    private TaskPressedWrong(int indexlabeldummy2){
    this.indexlabeldummy2 = indexlabeldummy2;
    }

    public void run() {

        audioWrong[nfieldsoundw].play();

        try {
            SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                jlblnumberField[indexlabeldummy2].setForeground(nfieldfcp);
                jlblnumberField[indexlabeldummy2].setBackground(nfieldbgcpw);
            }
            });

            Thread.sleep(250);

            SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                jlblnumberField[indexlabeldummy2].setForeground(nfieldfc);
                jlblnumberField[indexlabeldummy2].setBackground(nfieldbgc);
              }
            });

        }
        catch (InterruptedException ex) {

        }

    }
}

private class TaskPressedRight implements Runnable {
    private int indexlabeldummy2;

    public TaskPressedRight(int indexlabeldummy2){
    this.indexlabeldummy2 = indexlabeldummy2;
    }

    public void run() {

        audioRight[nfieldsoundr].play();
        try {
            SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                jlblnumberField[indexlabeldummy2].setForeground(nfieldfcp);
                jlblnumberField[indexlabeldummy2].setBackground(nfieldbgcpr);
              }
            });

            Thread.sleep(250);

            SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                jlblnumberField[indexlabeldummy2].setForeground(nfieldfc);
                jlblnumberField[indexlabeldummy2].setBackground(nfieldbgc);
               }
            });

        }
        catch (InterruptedException ex) {

        }
    }
}

Bei jedem Klick wird also ein neuer Thread erstellt, da man durchaus Geschwindigkeiten erreichen kann, bei der man pro Sekunde 3 - 4 Labels anklickt. Selbst wenn ich das Spiel komplett ohne Ton laufen lasse, habe ich noch immer das Problem mit der Färbung. Wer kann mir hier weiterhelfen?
Zuvor lies ich übrigens alles vom Hauptthread abarbeiten, (neben MausPressed war auch MouseReleased mit eingebunden). Hierbei zeigte sich das Phänomen auch schon.
Ich spekuliere ja darauf, dass man das irgendwie puffern muss. Im Übrigen zeigt sich das Phänomen bei Firefox und Google Chrom, egal ob ich das Spiel auf meinem alten Laptop oder auf meinem leistungsfähigen Desktop-PC laufen lasse.
 
Zuletzt bearbeitet:

Marco13

Top Contributor
Als erstes würde ich nicht jedes mal einen neuen Thread starten. Stattdessen die Aufgaben ("Richtig" oder "Falsch" ausgeben) z.B. in eine BlockingQueue legen, aus der der Thread sie sich abholt....
 

Fu3L

Top Contributor
Was hast du von Marcos Vorschlag umgesetzt?

Hier das Sun-Tutorial zu Marcos Vorschlag, falls du dir nichts darunter vorstellen kannst:
Guarded Blocks (The Java™ Tutorials > Essential Classes > Concurrency)

So verringerst du die Anzahl der Threads, was alleine schon mehr Performance bringen wird und wenn der Consumer-Thread alleine über das Abspielen des Sounds wacht, kann er sich selbst auch eine Variable setzen, ob gerade noch ein Sound spielt, ohne dass man mit synchronized oder volatile rumhantieren muss.
Du musst das obrige Beispiel natürlich so abändern, das der Consumer nicht auf eine neue Eingabe wartet, sondern dann mit seinem Loop fortfährt, weil du ja noch die Entfärbung des Labels vorrantreiben musst. (und evtl. den Sound weiter abspielen/beenden musst. Die Sound API ist mir relativ unbekannt. Ka, wie viel man da selbst machen muss^^)
 

JonnyAd

Mitglied
Ich habe nun 4 Threads integriert (2 für richtig/ 2 für falsch) dies sich dann immer ihre Aufgaben holen.
Klappt sehr gut. Signifikante Performancesteigerung. Selbst auf dem Laptop läuft's nun sehr gut.
Die Sounddatieien habe ich nun auch gepuffert:

Und zwar so:

Java:
            URL urlright = new URL("http://xxxxxxxx" + nfieldsoundr + ".wav");
            AudioInputStream audioInright = AudioSystem.getAudioInputStream(urlright);
            BufferedInputStream bufferedInputStreamr = new BufferedInputStream(audioInright);

            afr = audioInright.getFormat();
            sizer = (int) (afr.getFrameSize() * audioInright.getFrameLength());
            audior = new byte[sizer];
            infor = new DataLine.Info(Clip.class, afr, sizer);
            bufferedInputStreamr.read(audior, 0, sizer);
            rightSound= (Clip) AudioSystem.getLine(infor);
            rightSound.open(afr, audior, 0, sizer);

Bisher haben sich die Probleme noch nicht wieder gezeigt. Ich hoffe, dass es dabei auch bleibt.

JonnyAd
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
xFearofdarkness Feinde überlappen sich in Java Spiel Spiele- und Multimedia-Programmierung 3
K Mein Jump and Run charakter bewegt sich nicht mehr rückwärts... Spiele- und Multimedia-Programmierung 0
R Memory - Nicht alle Button lassen sich aktivieren? Spiele- und Multimedia-Programmierung 1
P Sich bewegende Kamera Spiele- und Multimedia-Programmierung 12
I Wo befindet sich ein Punkt? Spiele- und Multimedia-Programmierung 6
N der Player bewegt sich nicht Spiele- und Multimedia-Programmierung 14
R Game Loop verhält sich eigenartig Spiele- und Multimedia-Programmierung 1
A Spielball bewegt sich nicht richtig, prallt falsch ab Spiele- und Multimedia-Programmierung 7
Blender3D VLCJ Video lässt sich nicht mehr abspielen nach mysql Installation Spiele- und Multimedia-Programmierung 1
Androbin Mein Spiel will sich nicht zeichnen lassen !!! Spiele- und Multimedia-Programmierung 7
S Animation zieht "Spur" hinter sich her Spiele- und Multimedia-Programmierung 2
M Bildschirmgröße ändert sich Spiele- und Multimedia-Programmierung 10
M Würdet ihr sagen Java Applets eignen sich gut Spiele- und Multimedia-Programmierung 5
J Java3D - Farben vermischen sich Spiele- und Multimedia-Programmierung 7
E [LWJGL] Karusell, mehrere Objekte drehen sich um einen Mittelpunkt Spiele- und Multimedia-Programmierung 31
CookieSoft 3D Würfel will sich nicht drehen! [LWJGL] Spiele- und Multimedia-Programmierung 2
M Beim schießen richtet sich die Kugel nach der Maus aus (Quaternion) Spiele- und Multimedia-Programmierung 5
T JOGL im OrthoMode und Texturen verfärben sich Spiele- und Multimedia-Programmierung 3
S Programm hängt sich auf wenn Lied abspielt Spiele- und Multimedia-Programmierung 4
W 2 Bälle, die sich abstoßen Spiele- und Multimedia-Programmierung 24
F RPG - Spielfigur soll sich nicht frei bewegen können. Anregugen wären gerne gesehen^^ Spiele- und Multimedia-Programmierung 13
Ivan Dolvich [LWJGL] Texturen überlagern sich Spiele- und Multimedia-Programmierung 2
P JFileChooser öffnet sich drei mal Spiele- und Multimedia-Programmierung 4
Dragonfire Java Sound API - Lautstärke ändert sich nicht Spiele- und Multimedia-Programmierung 2
H Jogl-Animator - Inhalt ändert sich nicht Spiele- und Multimedia-Programmierung 4
M Sich nach links verschiebendes Bild Spiele- und Multimedia-Programmierung 2
L Figur soll sich selbständig Bewegen Spiele- und Multimedia-Programmierung 12
S Polygon bewegt sich nach mehreren aufrufen immer schneller Spiele- und Multimedia-Programmierung 3
B Bounds drehen sich nicht mit.... Spiele- und Multimedia-Programmierung 7
R Eignet sich Java für ein Beat'em'Up? Spiele- und Multimedia-Programmierung 3
R Kreuz lässt sich nicht zeichnen Spiele- und Multimedia-Programmierung 11

Ähnliche Java Themen

Neue Themen


Oben