简体   繁体   中英

Image files won't load in 2D Java game

So I am fairly new to Java and I built this Board for a snake game using a tutorial . It seems to work fine except for the fact that the image files won't load. I haven't worked with images in Eclipse before so I don't really know what I'm doing. I tried putting the .png image files in the package but that did not help at all. I would appreciate any ideas.

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Image;
import java.awt.Graphics;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;

import javax.swing.ImageIcon;
import javax.swing.JPanel;
import javax.swing.Timer;

public class Board extends JPanel implements ActionListener {

/**
 * 
 */
private static final long serialVersionUID = 1L;
private final int B_WIDTH = 300;
private final int B_HEIGHT = 300;
private final int DOT_SIZE = 10;
private final int ALL_DOTS = 900;
private final int  RAND_POS = 29;
private final int DELAY = 140;

private final int x[] = new int[ALL_DOTS];
private final int y[] = new int[ALL_DOTS];

private int dots;
private int apple_x;
private int apple_y;

private boolean leftDirection = false;
private boolean rightDirection = true;
private boolean upDirection = false;
private boolean downDirection = false;
private boolean inGame = true;

private Timer timer;
private Image ball;
private Image apple;
private Image head;

public Board() {
    addKeyListener(new TAdapter());
    setBackground(Color.black);
    setFocusable(true);

    setPreferredSize(new Dimension(B_WIDTH, B_HEIGHT));
    loadImages();
    initGame();
    }

private void loadImages() {

    ImageIcon iid = new ImageIcon("dot.png");
    ball = iid.getImage();

    ImageIcon iia = new ImageIcon("apple.png");
    apple = iia.getImage();

    ImageIcon iih = new ImageIcon("head.png");
    head = iih.getImage();
}

private void initGame() {

    dots = 3;

    for (int z = 0; z < dots; z++) {
        x[z] = 50 - z * 10;
        y[z] = 50;
    }

    locateApple();

    timer = new Timer(DELAY, this);
    timer.start();
}

@Override
public void paintComponent(Graphics g) {
    super.paintComponent(g);

    doDrawing(g);
}

private void doDrawing(Graphics g) {

    if (inGame) {

        g.drawImage(apple, apple_x, apple_y, this);

        for (int z = 0; z < dots; z++) {
            if (z == 0) {
                g.drawImage(head, x[z], y[z], this);
            } else {
                g.drawImage(ball, x[z], y[z], this);
            }
        }

        Toolkit.getDefaultToolkit().sync();
    } else {

        gameOver(g);
    }
}

private void gameOver (Graphics g) {

    String msg = "Game Over";
    Font small = new Font ("Helvetica", Font.BOLD, 14);
    FontMetrics metr = getFontMetrics(small);

    g.setColor(Color.white);
    g.setFont(small);
    g.drawString(msg, (B_WIDTH - metr.stringWidth(msg)) / 2, B_HEIGHT / 2);

}

private void checkApple(){

    if ((x[0] == apple_x) && (y[0] == apple_y)) {

        dots++;
        locateApple();
    }
}

private void move() {

    for (int z = dots; z > 0; z--) {

        x[z] = x[(z - 1)];
        y[z] = y[(z - 1)];
    }

    if (leftDirection) {
        x[0] -= DOT_SIZE;
    }

    if (rightDirection) {
        x[0] += DOT_SIZE;
    }

    if (upDirection) {
        y[0] -= DOT_SIZE;
    }

    if (downDirection) {
        y[0] += DOT_SIZE;
    }
}

private void checkCollision(){

    for (int z = dots; z > 0; z--) {

        if ((z > 4) && (x[0] == x[z]) && (y[0] == y[z])) {


        }
    }

   if (y[0] >= B_HEIGHT) {
            inGame = false;
        }

        if (y[0] < 0) {
            inGame = false;
        }

        if (x[0] >= B_WIDTH) {
            inGame = false;
        }

        if (x[0] < 0) {
            inGame = false;
        }

        if(!inGame) {
            timer.stop();
        }
}


private void locateApple() {

    int r = (int) (Math.random() * RAND_POS);
    apple_x = ((r * DOT_SIZE));

    r = (int) (Math.random() * RAND_POS);
    apple_y = ((r * DOT_SIZE));
}

@Override
public void actionPerformed(ActionEvent e) {

    if (inGame) {

        checkApple();
        checkCollision();
        move();
    }

    repaint();
}

private class TAdapter extends KeyAdapter {

    @Override
    public void keyPressed(KeyEvent e) {

        int key = e.getKeyCode();

        if ((key == KeyEvent.VK_LEFT) && (!rightDirection)) {
            leftDirection = true;
            upDirection = false;
            downDirection = false;
        }

        if ((key == KeyEvent.VK_RIGHT) && (!leftDirection)) {
            rightDirection = true;
            upDirection = false;
            downDirection = false;
        }

        if ((key == KeyEvent.VK_UP) && (!downDirection)) {
            upDirection = true;
            rightDirection = false;
            leftDirection = false;
        }

        if ((key == KeyEvent.VK_DOWN) && (!upDirection)) {
            downDirection = true;
            rightDirection = false;
            leftDirection = false;
        }
    }
}

}

Use ImageIO instead.

If you need an ImageIcon, create one from an image loaded through ImageIO. In this case the game isn't even using the Icon so don't bother, just use ImageIO to load a BufferedImage.

ImageIO.read() is overloaded to accept a File, InputStream or URL. So where your files need to be located depends on how you use it. Try putting your images in a specific location and use an absolute path to test:

private void loadImages() {
    ball = ImageIO.read(new File("c:/img/dot.png"));
}

Once you have that working you can refer to the general documentation around File or ClassLoader.getResource() on where files will be loaded from.

I don't use Eclipse however I suspect in general you probably want to:

  1. Put the image files into the same package as the Board class.
  2. Use getClass().getResourceAsStream(...) to get an InputStream.
  3. Convert the stream into an image.

Something like:

public void loadImages() {
    ball = ImageIO.read(getClass().getResourceAsStream("dot.png"));
} 

ImageIO also has the benefit of giving you more useful exceptions when loading fails too.

I tried putting the .png image files in the package

I would advise against putting the image files in the same package as the source files. In fact, a common hierarchy for source folders looks like this:

src/main/java
src/main/resources
src/test/java
src/test/resources

Within the src/main/java source folder, you can have your different packages for source files. Same for src/test/java, except they are test files.

In src/main/resources, you can place folders that contain all of the resource files (i18n files, images, etc.). These folders can be excluded from the build path and don't need to be source folders.

For example:

在此输入图像描述

Then, you should be able to do:

public static void main(String... args) {
    final ImageIcon imageIcon = new ImageIcon("src/main/resources/Desert.jpg");
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM