我开始学习用Java创建游戏,我正在使用的方法之一包括BufferedImage。这是我得到的错误:
"Exception in thread "main" java.lang.NullPointerException
at tm.Game.init(Game.java:48)
at tm.Game.<init>(Game.java:54)"
从这段代码:
package tm;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import javax.swing.JPanel;
@SuppressWarnings("serial")
public class Game extends JPanel implements Runnable {
private Settings Settings;
private Thread t;
private BufferedImage offscreenImage;
private Graphics offscr;
public void run() {
while(true) {
repaint();
try {
Thread.sleep(1000/30);
} catch (InterruptedException e) { }
}
}
public void paint(Graphics g) {
offscr.setColor(Color.blue);
offscr.fillRect(0, 0, Settings.GAME_WIDTH, Settings.GAME_HEIGHT);
offscr.setColor(Color.white);
offscr.drawString("Lolz", 10, 10);
g.drawImage(offscreenImage, 0, 0, this);
}
public void update(Graphics g) {
paint(g);
}
public void init() {
t = new Thread(this);
t.start();
offscreenImage = (BufferedImage) createImage(Settings.GAME_WIDTH, Settings.GAME_HEIGHT);
offscr = offscreenImage.getGraphics();
}
public Game() {
Settings = new Settings();
init();
}
}
设置类:
package tm;
public class Settings {
public final int GAME_WIDTH = 500;
public final int GAME_HEIGHT = 500;
}
屏幕等级:
package tm;
import javax.swing.JFrame;
public class Screen extends JFrame {
private static final long serialVersionUID = 1L;
private JFrame mainScreen;
private Game mainGame;
private Settings Settings;
public Screen() {
mainGame = new Game();
Settings = new Settings();
mainScreen = new JFrame();
mainScreen.add(mainGame);
mainScreen.setSize(Settings.GAME_WIDTH, Settings.GAME_HEIGHT);
mainScreen.setTitle("Lolz");
mainScreen.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
mainScreen.setResizable(false);
mainScreen.setVisible(true);
}
public static void main(String[] args) {
new Screen();
}
}
答案 0 :(得分:3)
返回null的不是getGraphics()
,而是前一个函数createImage()
。来自createImage()
的组件文档:
返回屏幕外可绘制图像,可用于双倍图像 缓冲。 如果组件不是,则返回值可以为null 可显示的。如果,这将永远发生 GraphicsEnvironment.isHeadless()返回true。
在offscreenImage上调用getGraphics()
时,你会得到一个NullPointerException,它是空的。
答案 1 :(得分:1)
抛出NullPointer异常的原因是你在错误的位置初始化了offScreenImage和offScr。
offscreenImage = (BufferedImage) createImage(Settings.GAME`WIDTH, Settings.GAME_HEIGHT);
offscr = offscreenImage.getGraphics();
此代码应该在函数paint中。为了得到结果,Game类应该像这样定义。另外一个提示最好将变量inn settings类声明为public static final,以便可以以静态方式访问它们。如下定义,对您的Game类进行少许更改。我认为这应该对你有帮助。
package tm;
import javax.swing.JPanel;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import tm.Screen.Settings;
public class Game extends JPanel implements Runnable {
// private Setting Settings;
private Thread t;
private BufferedImage offscreenImage;
private Graphics offscr;
public void run() {
while (true) {
repaint();
try {
Thread.sleep(1000 / 30);
} catch (InterruptedException e) {
}
}
}
public void paint(Graphics g) {
if (offscreenImage == null) {
offscreenImage = (BufferedImage) createImage(Settings.GAME_WIDTH,
Settings.GAME_HEIGHT);
}
offscr = offscreenImage.getGraphics();
offscr.setColor(Color.black);
offscr.fillRect(0, 0, Settings.GAME_WIDTH, Settings.GAME_HEIGHT);
offscr.setColor(Color.white);
offscr.drawString("Lolz", 10, 10);
g.drawImage(offscreenImage, 0, 0, this);
}
public void update(Graphics g) {
paint(g);
}
public void init() {
t = new Thread(this);
t.start();
}
public Game() {
init();
}
}
答案 2 :(得分:0)
因为createImage仅在Component“可显示”之后才能工作,例如它附加到一个可见的JFrame,你当前的代码不会工作。
有几种方法可以解决它。
将JFrame作为参数添加到ctor并在调用create component之前将Game添加到JFrame - 只要JFrame.add不调用部分初始化的Game实例覆盖的任何方法,这应该有效。
Game(JFrame jf){
jf.add(this);
...
}
JFrame mainFrame = new JFrame();
mainFrame.setVisible(true);
Game game = new Game(mainFrame);
在将游戏添加到JFrame后调用另一个init方法。这很难看,因为在调用此方法之前,Game对象尚未完全初始化。
Game game = new Game();
JFrame mainFrame = new JFrame();
mainFrame.add(game);
mainFrame.setVisible(true);
game.init();
One way找出组件可显示的时间是监听HierarchyEvent。您可以修改答案中显示的监听器来调用createImage而不是打印“显示”。 (该答案提供的课程也需要extends HierarchyListener
才能工作)