Methoden JLabel nach Mausklick erstellen und konsequent in eine Richtung bewegen.

SeeDevils

Mitglied
Hallo,

Ich habe jetzt folgendes Problem: Ich möchte ein Spiel erstellen, wo ein Charakter im grundlegendem Objekte abschießen muss die sich auf ihn zu bewegen. Ich habe zurzeit schon den Charakteren, welcher sich schon bewegen kann und auch schon, dass er auf Mausklick ein Schuss erstellen kann. Jedoch kriege ich es nicht hin das JLabel vom Schuss zu bewegen. Hier ist folgender Code:
Java:
public void schuss() {
        int startX = Figur.getX() + 50;
        int startY = Figur.getY() + 50;
        Schuss = new JLabel();
        Schuss.setBounds(startX, startY, 10, 10);
        Schuss.setBorder(Rahmen);
        Feld.add(Schuss);
        Schuss.setVisible(true);
        
        while(Schuss.getX() < 1920) {
            Schuss.setLocation(Schuss.getX() + 100, Schuss.getY());
            System.out.println(Schuss.getX() + "   -   " + Schuss.getY());
            
            try{
                 Thread.sleep(1000);
            }
            catch(InterruptedException e){}
            }
        Schuss.remove(this);
        
    }
(Die Methode Schuss habe ich nur in ein Mauslistener gesteckt)
Meine Probleme:
1. Ich erkenne das JLabel nicht, aber wenn ich die Schleife weglasse und Schuss.remove(this) ebenfalls erkenne ich das JLabel, mit den Beiden aber nicht.
2. Das Programm bleibt während des Vorgangs stecken.

Was ich eigenlich damit ereichen möchte :) : Mehrere Schuss gleichzeitig mehreren Mausklick erstellen die in einer Richtung fliegen.
(P.S: Ich habe es, um es für den Anfang leichter zu machen, nur X verschobe, später möchte ich aber Y miteinbeziehen. Zudem darf ich als Grafikausgabe AWT und Swing verwenden, heist wenn es nicht mit einem JLabel funktioniert, kann man es anders versuchen.)

LG
 

mihe7

Top Contributor
Du blockierst den Event Dispatch Thread, so dass das UI nicht aktualisiert werden kann. Die Schleife muss in einem separaten Thread ausgeführt werden (oder Du verwendest gleich einen Timer).
 
Beste Antwort

mihe7

Top Contributor
Naja, man startet einen Thread, indem man ein neues Thread-Objekt erzeugt und dessen start-Methode aufruft:

Java:
Thread th = new Thread(new Runnable() {
    public void run() {
        // hier Code, der im Hintergrund laufen soll
    }
});
th.start();

Wichtig ist, dass Änderungen am GUI im Event Dispatch Thread (EDT) ablaufen. Das erreichst Du, indem Du SwingUtilities.invokeLater() verwendest (die Methode erwartet wie Thread ein Runnable).

Alternativ kannst Du auch einen SwingWorker verwenden (Doku: https://docs.oracle.com/javase/8/docs/api/javax/swing/SwingWorker.html).

Für Animationen bietet sich auch ein Swing-Timer an (Doku: https://docs.oracle.com/javase/8/docs/api/javax/swing/Timer.html). Die actionPerformed-Methode des übergebenen ActionListener läuft automatisch im EDT.
 

SeeDevils

Mitglied
Also ich bin jetzt soetwas gekommen: (mit deiner Hilfe halt ^^):
Java:
    public void schuss() {
        int startX = Figur.getX() + 50;
        int startY = Figur.getY() + 50;
        Schuss = new JLabel("");
        Schuss.setBounds(startX, startY, 10, 10);
        Schuss.setBorder(Rahmen);
        Feld.add(Schuss);
        Schuss.setVisible(true);
        Schuss.setName(Integer.toString(name));
        Thread th = new Thread(new Runnable() {
        public void run() {
            while(Schuss.getX() < 1920) {
                SwingUtilities.invokeLater(new Runnable()
                {
                 public void run()
                    {   
                     Schuss.setLocation(Schuss.getX() + 10, Schuss.getY());
                     System.out.println(Schuss.getX() + "   -   " + Schuss.getY()); }
                 });
                    try{
                          Thread.sleep(1);
                    }
                    catch(InterruptedException e){}
            }}
        });
        th.start();
        Schuss.remove(this);
    }
Jetzt habe ich zwei Fragen:
1. Muss ich den Thread stoppen? (wenn ja muss ich es mit einem Flag machen?)
2. Wie kann ich mehrere Schüsse gleichzeichtig über das Feld laufen lassen?

LG
 

SeeDevils

Mitglied
Nein, also ich habe es ausprobiert und in dem Moment wo ein neuer JLabel erstellt wird, wird der anderere "zum stehen gebracht", was meiner Meinung nach Sinn ergibt, was ich aber nicht haben möchte ^^.

LG
 

Neue Themen


Oben