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);
}
}
It worked until I wrote this line of code (24 in Ball.java):
if (board.ball.intersects(board.pPaddle))
I’m getting error:
Exception in thread “Thread-0” java.lang.NullPointerException at
Ball$1.run(Ball.java:24) at java.lang.Thread.run(Unknown Source)
I’m sure that rectangles in GameBoard.java aren’t empty. I don’t know what to do.
As far as I can see, there are 2 possibilities:
board, the argument passed to the Ball’s constructor, is nullboard, the argument passed to the Ball’s constructor, is not null but because you start a thread in the constructor, the thread can see your Ball object partially constructed (and for example, ball.board might have not been assigned yet)…What you sould do:
boardis not null (with a print statement for example)You can create the thread in the consctructor and provide another method (start or init for example) that starts the thread.
Once you have done that, you will probably not get your NPE any longer. However, note that the line
Ball b = new Ball(this);is executed beforeRectangle ball = new Rectangle(500, 10, 10, 10);so if you accessboard.ballin the Ball’s constructor, you will see it null.In general, you should avoid escaping
thisin the constructor or an instance initializer (i.e. don’t write something likeObjectXX o = new ObjectXX(this);) becausethismight not be fully constructed.