简体   繁体   English

图像文件不会加载到2D Java游戏中

[英]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 . 所以我对Java很新,我使用教程为蛇游戏构建了这个Board。 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. 我之前没有使用Eclipse中的图像,所以我真的不知道我在做什么。 I tried putting the .png image files in the package but that did not help at all. 我尝试将.png图像文件放在包中,但这根本没有帮助。 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. 请改用ImageIO。

If you need an ImageIcon, create one from an image loaded through ImageIO. 如果需要ImageIcon,请从通过ImageIO加载的图像中创建一个。 In this case the game isn't even using the Icon so don't bother, just use ImageIO to load a BufferedImage. 在这种情况下,游戏甚至不使用Icon,所以不要打扰,只需使用ImageIO加载BufferedImage。

ImageIO.read() is overloaded to accept a File, InputStream or URL. 重载ImageIO.read()以接受File,InputStream或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. 一旦你有了这个工作,你可以参考FileClassLoader.getResource()的一般文档,在哪里加载文件。

I don't use Eclipse however I suspect in general you probably want to: 我不使用Eclipse但是我怀疑你可能想要:

  1. Put the image files into the same package as the Board class. 将图像文件放入与Board类相同的包中。
  2. Use getClass().getResourceAsStream(...) to get an InputStream. 使用getClass().getResourceAsStream(...)来获取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. ImageIO还可以在加载失败时为您提供更多有用的异常。

I tried putting the .png image files in the package 我尝试将.png图像文件放在包中

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. 在src / main / java源文件夹中,您可以拥有源文件的不同包。 Same for src/test/java, except they are test files. 对于src / test / java也是如此,除了它们是测试文件。

In src/main/resources, you can place folders that contain all of the resource files (i18n files, images, etc.). 在src / main / resources中,您可以放置​​包含所有资源文件的文件夹(i18n文件,图像等)。 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");
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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