JLabel bzw. Image Icon mit KeyEvent bewgen

jmoerni

Mitglied
Java:
package Game;

import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;
import javax.swing.JLabel;
import javax.swing.ImageIcon;

public class GameFrame extends JFrame implements ActionListener, KeyListener {

    int x = 60, y = 400, stern_x = 0, stern_y = 0;
 
    private JPanel contentPane;

    /**
     * Launch the application.
     */
    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            public void run() {
                try {
                    GameFrame frame = new GameFrame();
                    frame.setVisible(true);
                } catch (Exception e) {
                    e.printStackTrace();
                 
                }
            }
        });
    }

    /**
     * Create the frame.
     */
    public GameFrame() {
 
     
     
 
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setBounds(100, 100, 1000, 700);
        contentPane = new JPanel();
        contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
        setContentPane(contentPane);
        contentPane.setLayout(null);
     
        JLabel lbl_wolken = new JLabel("");
        lbl_wolken.setIcon(new ImageIcon("C:\\Users\\xyz\\Desktop\\divImage\\wolken.png"));
        lbl_wolken.setBounds(0, 0, 984, 150);
        lbl_wolken.setOpaque(true);
        contentPane.add(lbl_wolken);

        JLabel lbl_stern = new JLabel("");
        lbl_stern.addKeyListener(this);
        lbl_stern.setIcon(new ImageIcon("C:\\Users\\xyz\\Desktop\\divImage\\Stern.png"));
        lbl_stern.setBounds(x, y, 50, 50);
        lbl_stern.setOpaque(true);
        contentPane.add(lbl_stern);
     
        JLabel lbl_hintergrund = new JLabel("");
        lbl_hintergrund.setIcon(new ImageIcon("C:\\Users\\xyz\\Desktop\\divImage\\HintergundLeer.png"));
        lbl_hintergrund.setBounds(0, 0, 984, 661);
        lbl_hintergrund.setOpaque(false);
        contentPane.add(lbl_hintergrund);
    }
 
    public void actionPerformed(ActionEvent e) {
     
        if(x < 50) {
            stern_x = 0;
            x = 50;
        }
 
        if(x > 900) {
            stern_x = 0;
            x = 900;
        }
 
        if(y < 0) {
            stern_y = 0;
            y = 500;
        }
 
        if(y > 500) {
            stern_y = 0;
            y = 500;
        }
 
        x = x + stern_x;
        y = y + stern_y;
      
    }
 
 
    public void keyTyped(KeyEvent e) {
 
    }
 
 
    public void keyPressed(KeyEvent e) {
        if(e.getKeyCode() == KeyEvent.VK_W) {
            stern_x = 0;
            stern_y = -1;
        }
        if(e.getKeyCode() == KeyEvent.VK_S) {
            stern_x = 0;
            stern_y = 1;
        }
 
        if(e.getKeyCode() == KeyEvent.VK_A) {
            stern_x = -1;
            stern_y = 0;
        }
        if(e.getKeyCode() == KeyEvent.VK_D) {
            stern_x = 1;
            stern_y = 0;
        }
    }
 
 
    public void keyReleased(KeyEvent e) {
        stern_x = 0;
        stern_y = 0;
    }
 
 

}






Guten Abend, ich bin noch recht grün hinter den Ohren und benötige eure Hilfe.
Ich habe bisher ein Fenster erstellt und 3 Bilder über JLabel/ImageIcon eingefügt.
Die ersten "Probleme" hatte ich mit der Darstellung von übereinander liegenden Bildern. Das konnte ich inzwischen lösen.(Ob es so richtig ist weis ich nicht..hat aber geklappt) 😉
Das erste Bild Stellt den Hintergrund dar, das zweite Bild ist teil des Hintergrunds liegt aber übergelagert auf dem eigentlichen Hintergrundbild.
Das 3 Bild versuche ich grade über ein KeyEvent zu steuern.
Habt bitte Rücksicht mit mir und meiner Unwissenheit..
Sieht jemand woran es liegen könnte oder ist bereit mir sein Wissen darüber mitzuteilen?
Gruß
 
Zuletzt bearbeitet:
Du hast dem Sternen-Bild bei setBounds zwar Klassenweite x und y Variablen übergeben, aber das Bild platziert sich nicht automatisch neu wenn sich die Variablen verändern. Du musst erneut setBounds an dem Bild aufrufen wenn sich hier etwas verändern soll, ggf. brauchst du sogar noch ein revalidate auf das gesamte Frame/Panel.

Wenn du ein Spiel machen möchtest und dabei auf Standard Java bleiben möchtest würde ich dir empfehlen das ganze selber zu "malen" über eine überschriebene paintComponent Methode im Panel/Frame, dazu findet man sicherlich ein paar Guides/Tutorials auf Google/Youtube!

Liebe Grüße
Times
 
Zuletzt bearbeitet:
Ich hab noch eine weitere Frage, ich hab mich nach deinem Hinweis nochmal dran gesetzt und das ganze mit paint.Component geschrieben. Leider bin ich grade wieder an dem Punkt angelangt den ich im oberern Code bereits gelöst habe. Kann es sein das ich .setOpaque(false); nur am Label anwenden kann? Beim Laden des Fensters sehe ich für einen Bruchteil einer Sekunde das 2. Hintergrundbild. dieses wird vom anderen überdeckt da es als letzte Anweisung aufgerufen wird.
Wie setzte ich es in diesem Fall um verschiedene ebenen der Bilder zu zuweisen?
Ich habe es getestet und das 2. Bild nach unten verschoben, danach waren beide Bilder zu sehen jedoch das 2. natürlich um 150p nach unten abgeschnitten.
Code:
[CODE=java]protected void paintComponent(Graphics g) {

        

        super.paintComponent (g);

        

          Graphics2D g2d = (Graphics2D) g;

          g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);

        

          g.drawImage(Var.hintergrund1, Var.backgroundX1, 0, 1000, 150, null);

          g.drawImage(Var.hintergrund2, Var.backgroundX2, 0, 1000, 150, null);

          g.drawImage(Var.hintergrund3, Var.backgroundX3, 150, 1000, 700, null);

          g.drawImage(Var.hintergrund4, Var.backgroundX4, 150, 1000, 700, null);

          repaint();

    }
[/CODE]
 
Zuletzt bearbeitet:
Das was du vor hast ist nicht so trivial.... Im Prinzip suchst du nach der Physik eines Billardtisches: https://www.real-world-physics-problems.com/physics-of-billiards.html . Ich muss zugeben, diesen Link nicht ganz gelesen zu haben, aber ich habe mal ein kleines, funktionierendes Beispiel vorbereitet (ähnlich wie mihe):

Java:
import javax.imageio.ImageIO;
import javax.swing.*;
import java.awt.*;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Random;
import java.util.Timer;
import java.util.TimerTask;

public class Bilderwolke {
    private static final Random random = new Random();
    private static final int w = 500;
    private static final int h = 500;

    public static class Bild {
        BufferedImage ii;
        Rectangle2D pos;
        Point2D dir;

        public Bild(String path) throws IOException {
            ii = ImageIO.read(new File(path));
            pos = new Rectangle2D.Double(0, 0, ii.getWidth(), ii.getHeight());
            randomizePos();
            dir = new Point2D.Double(random.nextDouble() - 0.5, random.nextDouble() - 0.5);
            normalizeDir();
        }

        private void randomizePos() {
            int x = random.nextInt(w - (int) pos.getWidth());
            int y = random.nextInt(h - (int) pos.getWidth());
            pos.setRect(x, y, pos.getWidth(), pos.getHeight());
        }

        private void normalizeDir() {
            double a = Math.sqrt(dir.getX() * dir.getX() + dir.getY() * dir.getY());
            dir.setLocation(dir.getX() / a, dir.getY() / a);
        }

        public boolean intersectsBorder(int b) {
            return switch (b) {
                case 0 -> pos.getX() < 0;
                case 1 -> pos.getX() + pos.getWidth() > w;
                case 2 -> pos.getY() < 0;
                case 3 -> pos.getY() + pos.getHeight() > h;
                default -> false;
            };
        }

        public boolean intersects(Bild other) {
            return this != other && pos.intersects(other.pos);
        }

        public void changeDirBorder(int b) {
            switch (b) {
                case 0, 1 -> dir.setLocation(dir.getX() * -1, dir.getY());
                case 2, 3 -> dir.setLocation(dir.getX(), dir.getY() * -1);
            }
            move(15);
        }

        public void changeDir(Bild other) {
            dir.setLocation(dir.getX() * -1, dir.getY() * -1);
            other.dir.setLocation(other.dir.getX() * -1, other.dir.getY() * -1);
            move(15);
        }

        public void draw(Graphics g2d) {
            g2d.drawImage(ii, (int) pos.getX(), (int) pos.getY(), null);
        }

        public void move(double b) {
            pos.setRect(dir.getX() * b + pos.getX(), dir.getY() * b + pos.getY(), pos.getWidth(), pos.getHeight());
        }
    }

    public static void main(String[] args) throws IOException {
        ArrayList<Bild> bilds = new ArrayList<>();
        bilds.add(new Bild("a.png"));
        bilds.add(new Bild("b.png"));
        bilds.add(new Bild("c.png"));
        JPanel canvas = new JPanel() {
            @Override
            protected void paintComponent(Graphics g) {
                super.paintComponent(g);
                g.clearRect(0, 0, w, h);
                for (Bild b : bilds) {
                    for (int i = 0; i < 4; i++) {
                        if (b.intersectsBorder(i)) {
                            b.changeDirBorder(i);
                            break;
                        }
                    }
                    for (Bild b2 : bilds) {
                        if (b.intersects(b2)) {
                            b.changeDir(b2);
                            break;
                        }
                    }
                    b.draw(g);
                    b.move(10);
                }
            }
        };
        canvas.setPreferredSize(new Dimension(w, h));
        JFrame f = new JFrame();
        f.add(canvas);
        f.pack();
        f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        f.setVisible(true);
        new Timer().schedule(new TimerTask() {
            @Override
            public void run() {
                SwingUtilities.invokeLater(canvas::repaint);
            }
        }, 50, 50);
    }
}

Das braucht aber noch ein bisschen Feintuning, weil es bei bestimmten Konstellationen passieren kann das Bilder "herausgeschleudert" werden... (ähnlich wie beim echten Billardtisch)...
 
Und noch weitergehende Links:


 

Zurück
Oben