0

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.NullPointerExceptionatBall $ 1.run(Ball.java:24)at java.lang.Thread.run(Unknown Source)

GameBoard.javaの長方形は空ではないと確信しています。どうしたらいいのかわからない。

4

2 に答える 2

1

私が見る限り、2つの可能性があります:

  • board、Ballのコンストラクターに渡される引数はnullです
  • board、Ballのコンストラクターに渡される引数はnullではありませんが、コンストラクターでスレッドを開始するため、スレッドはBallオブジェクトが部分的に構築されていることを確認できます(たとえば、ball.boardがまだ割り当てられていない可能性があります)。

あなたがすべきこと:

  1. nullでないことを確認しboardます(たとえば、printステートメントを使用)
  2. いずれにせよ、コンストラクターで新しいスレッドを開始しないでください

コンストラクターでスレッドを作成し、スレッドを開始する別のメソッド(たとえば、startまたはinit)を提供できます。


それを実行すると、おそらくNPEを取得できなくなります。ただし、この行Ball b = new Ball(this);は前に実行されるRectangle ball = new Rectangle(500, 10, 10, 10);ため、Ballのコンストラクターでアクセスboard.ballすると、nullが表示されることに注意してください。

一般に、完全に構築されていない可能性があるためthis、コンストラクターまたはインスタンス初期化子でエスケープすることは避けてください(つまり、のようなものを記述しないでくださいObjectXX o = new ObjectXX(this);) 。this

于 2012-07-09T09:52:26.597 に答える
0

ボールの四角形は null である可能性が非常に高いため、まず、board.ballにアクセスしようとするスレッドを開始する b を作成します。ballは後で GameBoard コンストラクターで作成されます。

于 2012-07-09T09:54:35.353 に答える