ImageIO Reader错误和问题

时间:2018-04-24 15:35:13

标签: java

我正在用Java创建一个非常基本的游戏,用于几天内到期的英语项目(任何答案都会受到赞赏!)。

我在编译和加载图像时遇到问题:在我的IDE,IntelliJ中,我可以轻松加载图像,但使用src/main/resources/assets/image.png这样的直接路径。但是我的程序结构合理,所以它适用于Gradle,我真的应该只需要assets/image.png

然而,主要问题是当我运行./gradlew jar将其编译成可执行的.jar文件时,无论我使用何种路径,它都不会找到图像。

有人可以帮忙提一些建议吗?我用ImageIO等尝试了很多方法。我找不到适用于StackOverflow的解决方案。

这是我的代码:(一些不相关的东西,如KeyAdapters省略。这真是凌乱和糟糕的代码,但我只是希望它能够正常运行)

public class Game implements Runnable {

    final int WIDTH = 1000;
    final int HEIGHT = 700;

    JFrame frame;
    Canvas canvas;
    BufferStrategy bufferStrategy;

    public Game() {
        frame = new JFrame("Hamlet Game by Brian Shin");

        JPanel panel = (JPanel) frame.getContentPane();
        panel.setPreferredSize(new Dimension(WIDTH, HEIGHT));
        panel.setLayout(null);

        canvas = new Canvas();
        canvas.setBounds(0, 0, WIDTH, HEIGHT);
        canvas.setIgnoreRepaint(true);

        panel.add(canvas);

        canvas.addMouseListener(new MouseControl());
        canvas.addKeyListener(new KeyControl());

        frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        frame.pack();
        frame.setResizable(false);
        frame.setVisible(true);

        canvas.createBufferStrategy(2);
        bufferStrategy = canvas.getBufferStrategy();

        canvas.requestFocus();
    }

    //Key adapter and Mouse stuff here

    Sprite background;
    Sprite hamlet;

    public void initGame() {

        // TESTING
        /*ImageIcon bg = new ImageIcon("src/main/resources/bg.png");
        background = new Sprite(bg.getImage(), 0, 0);

        ImageIcon hammy = new ImageIcon("src/main/resources/hamlet.png");
        hamlet = new Sprite(hammy.getImage(), 300, 300); */

        BufferedImage bg;
        BufferedImage hammy;
        try {
            bg = ImageIO.read(new File("src/main/resources/assets/bg.png")); // TODO: get it working with .jar compiler
            hammy = ImageIO.read(new File("src/main/resources/assets/hamlet.png")); // src/main/resources/assets
            background = new Sprite(bg, 0, 0);
            hamlet = new Sprite(hammy, 300, 300);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    long desiredFPS = 60;
    long desiredDeltaLoop = (1000*1000*1000)/desiredFPS;
    boolean running = true;

    public void run() {

        long beginLoopTime;
        long endLoopTime;
        long currentUpdateTime = System.nanoTime();
        long lastUpdateTime;
        long deltaLoop;

        initGame();

        while(running) {
            beginLoopTime = System.nanoTime();

            render();

            lastUpdateTime = currentUpdateTime;
            currentUpdateTime = System.nanoTime();
            update((int) ((currentUpdateTime - lastUpdateTime)/(1000*1000)));

            endLoopTime = System.nanoTime();
            deltaLoop = endLoopTime - beginLoopTime;

            if(deltaLoop > desiredDeltaLoop) {
                //Do nothing.
            } else {
                try {
                    Thread.sleep((desiredDeltaLoop - deltaLoop)/(1000*1000));
                } catch(InterruptedException e) {
                    //Do nothing.
                }
            }
        }
    }

    private void render() {
        Graphics2D g = (Graphics2D) bufferStrategy.getDrawGraphics();
        g.clearRect(0, 0, WIDTH, HEIGHT);
        g.drawImage(background.getImage(), background.getX(), background.getY(), null);
        render(g);
        g.dispose();
        bufferStrategy.show();
    }

    /**
     * Update method.
     */
    protected void update(int deltaTime) {
    }

    /**
     * Main rendering method.
     */
    protected void render(Graphics2D g) {
        g.drawImage(hamlet.getImage(), hamlet.getX(), hamlet.getY(), null);
    }

    public boolean collision(Sprite s) {
        return (s.getX() < 0 || s.getY() < 0 || s.getX() > (WIDTH - 30) || s.getY() > (HEIGHT - 45));
    }

    public Direction getCollDir(Sprite s) {
        if(s.getX() < 0) {
           return Direction.LEFT;
        } else if(s.getY() < 0) {
            return Direction.UP;
        } else if(s.getX() > (WIDTH - 30)) {
            return Direction.RIGHT;
        } else if(s.getY() > (HEIGHT - 45)) {
            return Direction.DOWN;
        } else {
            return Direction.NONE;
        }
    }

    public static void main(String [] args) {
        Game ex = new Game();
        new Thread(ex).start();
    }

} 

产生的错误是:

javax.imageio.IIOException: Can't read input file!
        at javax.imageio.ImageIO.read(Unknown Source)
        at Game.initGame(Game.java:151)
        at Game.run(Game.java:172)
        at java.lang.Thread.run(Unknown Source)
Exception in thread "Thread-2" java.lang.NullPointerException
        at Game.render(Game.java:201)
        at Game.run(Game.java:177)
        at java.lang.Thread.run(Unknown Source)

1 个答案:

答案 0 :(得分:0)

您应该使用ImageIO.read(InputStream input)代替ImageIO.read(File file) 然后将该文件作为类路径资源加载,将其作为流传递:Game.class.gerResourceAsStream("/bg.png");

如果图像位于jar内的目录下,只需在文件名前面附加目录路径。