我正在用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)
答案 0 :(得分:0)
您应该使用ImageIO.read(InputStream input)
代替ImageIO.read(File file)
然后将该文件作为类路径资源加载,将其作为流传递:Game.class.gerResourceAsStream("/bg.png");
如果图像位于jar内的目录下,只需在文件名前面附加目录路径。