Ball.java
public class Ball {
int x = 500, y = 10, speed = 1;
GameBoard board;
boolean keepRunning = true;
Thread thread;
Ball(GameBoard board) {
this.board = board;
new Thread(r1).start();
}
public int getX() {
return x;
}
public int getY() {
return y;
}
Runnable r1 = new Runnable() {
public void run() {
try {
while (true) {
if (board.ball.intersects(board.pPaddle)) {
speed = -speed;
} else {
System.out.println(board.ball + " z " + board.pPaddle);
}
x -= speed;
board.repaint();
Thread.sleep(10L);
}
} catch (InterruptedException iex) {
}
}
};
}
GameBoard.java
@SuppressWarnings("serial")
public class GameBoard extends Canvas {
Image dbi;
Graphics db;
JFrame okno;
Player p = new Player(this);
Ball b = new Ball(this);
Ai a = new Ai(this);
Rectangle aiPaddle = new Rectangle(10, 590, 10, 50);
Rectangle pPaddle = new Rectangle(10, 100, 10, 50);
Rectangle ball = new Rectangle(500, 10, 10, 10);
GameBoard() {
okno = new JFrame();
okno.setTitle("Pink Ponk");
okno.setSize(600, 300);
okno.getContentPane().setBackground(Color.black);
okno.setResizable(false);
okno.setVisible(true);
okno.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
addKeyListener(p);
}
public static void main(String[] args) {
GameBoard gra = new GameBoard();
gra.okno.add(gra);
}
@Override
public void update(Graphics g) {
pPaddle.setBounds(p.getX(), p.getY(), 10, 50);
aiPaddle.setBounds(a.getX(), a.getY(), 10, 50);
ball.setBounds(b.getX(), b.getY(), 10, 10);
dbi = createImage(10, 50);
db = dbi.getGraphics();
paint(db);
g.clearRect(0, 0, 600, 300);
g.drawRect(p.getX(), p.getY(), 10, 50);
g.fillRect(p.getX(), p.getY(), 10, 50);
g.drawOval(b.getX(), b.getY(), 10, 10);
g.fillOval(b.getX(), b.getY(), 10, 10);
}
@Override
public void paint(Graphics g) {
pPaddle.setBounds(p.getX(), p.getY(), 10, 50);
aiPaddle.setBounds(a.getX(), a.getY(), 10, 50);
ball.setBounds(b.getX(), b.getY(), 10, 10);
g.clearRect(0, 0, 600, 300);
g.setColor(Color.white);
g.drawRect(p.getX(), p.getY(), 10, 50);
g.fillRect(p.getX(), p.getY(), 10, 50);
g.drawOval(b.getX(), b.getY(), 10, 10);
g.fillOval(b.getX(), b.getY(), 10, 10);
}
}
直到我编写这行代码(Ball.java中的24):
if (board.ball.intersects(board.pPaddle))
我收到错误:
线程“Thread-0”中的异常java.lang.NullPointerException at 来自java.lang.Thread.run的球$ 1.run(Ball.java:24)(未知来源)
我确定GameBoard.java中的矩形不是空的。我不知道该怎么做。
答案 0 :(得分:1)
据我所知,有两种可能性:
board
,传递给Ball的构造函数的参数为null board
,传递给Ball的构造函数的参数不是null,但是因为你在构造函数中启动一个线程,线程可以看到你的Ball对象部分构造(例如,ball.board可能没有已被分配)... 你应该做什么:
board
是否为空(例如使用打印语句)您可以在构造函数中创建线程,并提供另一个启动线程的方法(例如start或init)。
完成后,您可能不会再获得NPE了。但请注意,Ball b = new Ball(this);
行在Rectangle ball = new Rectangle(500, 10, 10, 10);
之前执行,因此如果您在Ball的构造函数中访问board.ball
,您将看到它为空。
通常,您应该避免在构造函数或实例初始值设定项中转义this
(即不要写ObjectXX o = new ObjectXX(this);
之类的内容)因为this
可能没有完全构造。
答案 1 :(得分:0)
球矩形很可能为空,你首先创建一个b,它会启动一个试图访问 board.ball 的线程。 ball 稍后会在GameBoard构造函数中创建。