2D-Grafik Bilder werden für mein Spiel nicht angezeigt

i8yourDog

Neues Mitglied
Hallo,
ich soll für die Schule ein Spiel programmieren. Grundsätzlich ist es gar nicht so kompliziert, denn es ist ein Button-Masher und es hat auch so ganz gut funktioniert.
Jedoch habe ich ein Problem. Ich möchte gerne die graphischen Kästen durch Bilder von Autos ersetzen. Ich habe es mit einem absoluten Pfad probiert aber die Bilder werden nicht angezeigt. Mit den "Kästen" hat es noch funktioniert. Was kann ich tun?
Danke


Java:
[/B]
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class MiniRacer extends JFrame implements KeyListener {
    private int Ferrari1 = 20; // Startposition Spieler 1
    private int BMW2 = 20;     // Startposition Spieler 2
    private final int ZIEL_LINIE = 1600; // Ziel-Linie
    private boolean gameOver = false;
    private RacePanel racePanel;
    private JLabel statusLabel;
    private Image ferrariF40bild;
    private Image bmwE36bild;
    public MiniRacer() {
        super("Mini Racer - 2 Spieler");
        setSize(1920, 745);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setLayout(new BorderLayout());
        // === Bilder laden === (8.10) (4.11)
        //ferrariF40bild = new ImageIcon("F40.png").getImage();
        //bmwE36bild = new ImageIcon("E36.png").getImage();
        ferrariF40bild = new ImageIcon("C:/Users/name/Desktop/Spiel/F40.png").getImage();
        bmwE36bild = new ImageIcon("C:/Users/name/Desktop/Spiel/E36.png").getImage();
       
        // 1.10. Schrift
        racePanel = new RacePanel();
        statusLabel = new JLabel("Spieler 1 = A | Spieler 2 = L | Ziel: rechts!", SwingConstants.CENTER);
        statusLabel.setFont(new Font(Font.SANS_SERIF, Font.BOLD, 16));
        add(racePanel, BorderLayout.CENTER);
        add(statusLabel, BorderLayout.SOUTH);
       
        addKeyListener(this); // (4.11.) "listening" auf die Tastatureingaben
        setFocusable(true); // (1.10.) setzt Fokus auf das Fenster
        setLocationRelativeTo(null); // (4.11.) Zentriert Fenster im Bildschirm
        setVisible(true); // (1.10.) macht das Fenster sichtbar
    }
    private class RacePanel extends JPanel {
        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            // Spielfeld
            g.setColor(Color.LIGHT_GRAY);
            g.fillRect(0, 55, getWidth(), 200);
            g.fillRect(0, 400, getWidth(), 200);
            // Ziellinie
            g.setColor(Color.BLACK);
            g.drawLine(ZIEL_LINIE, 0, ZIEL_LINIE, getHeight());
            // Autos zeichnen (8.10.) (4.11)
            g.drawImage(ferrariF40bild, Ferrari1, 55, 300, 300, this); // Bildgröße auch 300x300
            g.drawImage(bmwE36bild, BMW2, 400, 300, 300, this);
           
        }
    }
    @Override
    public void keyPressed(KeyEvent e) {
        if (gameOver) return;
        if (e.getKeyChar() == 'a') {
            Ferrari1 += 10;
        } else if (e.getKeyChar() == 'l') {
            BMW2 += 10;
        }
        checkWinner();
        racePanel.repaint();
    }
    private void checkWinner() {
        if (Ferrari1 >= ZIEL_LINIE) {
            statusLabel.setText("Spieler 1 (Ferrari F40) hat gewonnen!");
            gameOver = true;
        } else if (BMW2 >= ZIEL_LINIE) {
            statusLabel.setText("Spieler 2 (BMW M3) hat gewonnen!");
            gameOver = true;
        }
    }
    @Override public void keyReleased(KeyEvent e) {}
    @Override public void keyTyped(KeyEvent e) {}
    public static void main(String[] args) {
        SwingUtilities.invokeLater(MiniRacer::new);
    }
       
}
[B]
 
Zuletzt bearbeitet:

KonradN

Super-Moderator
Mitarbeiter
Kannst Du noch mehr Details geben, was genau nicht funktioniert?

Prinzipiell nimmt der Konstruktor auch einen Filenamen, und so der Pfad stimmt (ggf. noch Gross-/Kleinschreibung prüfen!), dann sollte es klappen....

Ich sehe daher gerade keinen wirklichen Fehler. Es gibt Dinge, die man anders machen sollte aber das spielt erst einmal keine Rolle ... Und ich habe einen Pfad zu einem Bild eingefügt, das ich auf dem Rechner hatte und es lief direkt....
 

Robert Zenz

Top Contributor
Der Konstruktor von ImageIcon versagt leise wenn es das Bild nicht gibt, nicht gefunden wird, oder nicht geladen werden kann.

Daher waere es besser dass ueber die explizite Methode von ImageIO zu laden:

Java:
try (InputStream imageInputStream = Files.newInputStream(Paths.get("C:/Users/name/Desktop/Spiel/F40.png"))) {
   ferrariF40bild = ImageIO.read(imageInputStream);
} catch (IOException e) {
    e.printStackTrace();
}

Dann siehst du wenn es einen Fehler gibt beim laden vom Bild.

Wenn das Laden funktioniert, dann muss etwas beim Anzeigen nicht stimmen, zum Beispiel eine andre Bildgroesze oder aehnliches?
 

Blender3D

Top Contributor
Jedoch habe ich ein Problem. Ich möchte gerne die graphischen Kästen durch Bilder von Autos ersetzen. Ich habe es mit einem absoluten Pfad probiert aber die Bilder werden nicht angezeigt. Mit den "Kästen" hat es noch funktioniert. Was kann ich tun?
Danke
Also ich sehe das so wie Konrad, Robert und M.L. Es dürfte sich um ein Pfadproblem handeln. Du könntest in deinem Projektverzeichnis einen Ordner für die Bilder anlegen. Ich habe deinen Code etwas verändert und mit den Konstanten die du in deinem Code verwendest sprechende Namen gegeben. Dein KeyListener ist fehlerhaft, da sich die beiden Spieler beim Drücken der Tasten gegenseitig blockieren. Für die Autos habe ich außerdem eine weitere innere Klasse benutzt.
Hier der geänderte Code.

Java:
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingConstants;
import javax.swing.SwingUtilities;
import java.awt.Font;

@SuppressWarnings("serial")
public class MiniRacer extends JFrame {
    private final static String IMAGE_DIR = "./images/"; // Pfad des Ordners in dem die Bilder sind
    private final static int WIDTH = 920;
    private final static int HEIGHT = 345;
    /**
     * Alle weiteren Konstanten hängen von WIDTH und HEIGHT ab. Bei geänderten
     * Werten passen sie sich automatisch an. Die Namen der Konstanten beschreiben
     * auch deren Funktion. Dadurch lässt sich die Größe des Spiels bei Bedarf
     * schnell anpassen.
     */
    private final static int START_POS = WIDTH / 96;
    private final static int STREET_HEIGHT = (int) (HEIGHT / 3.725);
    private final static int CAR_WIDTH = (int) (STREET_HEIGHT * 1.5);
    private final static int FINISHLINE_POS = WIDTH - CAR_WIDTH - START_POS;
    private final static int POS_Y_STREET1 = HEIGHT / 14;
    private final static int POS_Y_STREET2 = (int) (HEIGHT / 1.8);

    // Wie der Racepanel ist auch Car eine innere Klasse die den Code vereinfacht.
    private Car bmw = new Car("E36.png", CAR_WIDTH, STREET_HEIGHT);
    private Car ferrari = new Car("F40.png", CAR_WIDTH, STREET_HEIGHT);

    private boolean gameOver = false;
    private RacePanel racePanel = new RacePanel();
    private JLabel statusLabel = new JLabel("", SwingConstants.CENTER);;

    private class Car {
        private int x;
        private int y;
        private int width;
        private int height;
        private int speed = 10;
        private Image image;

        public Car(String fileName, int width, int height) {
            this.width = width;
            this.height = height;
            try {
                image = ImageIO.read(new File(IMAGE_DIR + fileName));
                image = image.getScaledInstance(width, height, Image.SCALE_SMOOTH);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        public void draw(Graphics g) {
            if (image == null) {
                g.setColor(Color.RED);
                g.fillRect(x, y, width, height);
            } else
                g.drawImage(image, x, y, null);
        }

        public void move() {
            x += speed;
        }

        public void setPos(int x, int y) {
            this.x = x;
            this.y = y;
        }
    }

    private class RacePanel extends JPanel {
        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            // Spielfeld
            g.setColor(Color.LIGHT_GRAY);
            g.fillRect(0, POS_Y_STREET1, getWidth(), STREET_HEIGHT);
            g.fillRect(0, POS_Y_STREET2, getWidth(), STREET_HEIGHT);
            // Ziellinie
            g.setColor(Color.BLACK);
            g.drawLine(FINISHLINE_POS, 0, FINISHLINE_POS, getHeight());
            // Autos zeichnen (8.10.) (4.11)
            ferrari.draw(g);
            bmw.draw(g);
        }
    }

    public MiniRacer() {
        super("Mini Racer - 2 Spieler");
        setSize(WIDTH, HEIGHT);
        resetGame();
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setLayout(new BorderLayout());
        // 1.10. Schrift
        statusLabel.setFont(new Font(Font.SANS_SERIF, Font.BOLD, 16));
        add(racePanel, BorderLayout.CENTER);
        add(statusLabel, BorderLayout.SOUTH);
        addKeyListener(new KeyAdapter() {// (4.11.) "listening" auf die Tastatureingaben
            @Override
            public void keyReleased(KeyEvent e) {
                if (gameOver) { // ermöglicht einen Neustart des Spiels
                    if (e.getKeyChar() == 'r')
                        resetGame();
                    return;
                }
                if (e.getKeyChar() == 'a')
                    ferrari.move();
                else if (e.getKeyChar() == 'l')
                    bmw.move();
                gameOver = checkWinner();
                racePanel.repaint();
            }
        });
        setFocusable(true); // (1.10.) setzt Fokus auf das Fenster
        setLocationRelativeTo(null); // (4.11.) Zentriert Fenster im Bildschirm
        setVisible(true); // (1.10.) macht das Fenster sichtbar
        setResizable(false);
    }

    private boolean checkWinner() {
        if (ferrari.x >= FINISHLINE_POS) {
            statusLabel.setText("Spieler 1 (Ferrari F40) hat gewonnen! <R = restart game>");
            ferrari.x = FINISHLINE_POS;
            return true;
        } else if (bmw.x >= FINISHLINE_POS) {
            bmw.x = FINISHLINE_POS;
            statusLabel.setText("Spieler 2 (BMW M3) hat gewonnen! <R = restart game>");
            return true;
        }
        return false;
    }

    private void resetGame() {
        statusLabel.setText("Spieler 1 = A | Spieler 2 = L | Ziel: rechts!");
        ferrari.setPos(START_POS, POS_Y_STREET1);
        bmw.setPos(START_POS, POS_Y_STREET2);
        gameOver = false;
        repaint();
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(MiniRacer::new);
    }

}
 

Neue Themen


Oben