2

私の最後のプロジェクト(そして最大の:))はピンポンゲームです。「AI」を実装しようとしていますが、これができないためです。

Exception in thread "Timer-0" java.lang.NullPointerException
    at main.Ball$1.run(Ball.java:25)
    at java.util.TimerThread.mainLoop(Unknown Source)
    at java.util.TimerThread.run(Unknown Source)

私はコード全体をうまく書いたと思いますが、何かが間違っているに違いありません。

Main.java- http: //pastebin.com/nvHwQAFD

Ball.java- http: //pastebin.com/cgE5r5eW

Player.java-pastebin.com/7QeiNciz

Ai.java --pastebin.com / xsGhJ7Zb(2つのハイパーリンクのみ、スパム防止)

コードは良いスタイルで書かれていません、そして私はあなたが盲目にならないことを願っています:)

あいさつ、エイドリアン

4

3 に答える 3

8

競合状態があります。

コンストラクターを呼び出すと、問題のあるコードをスケジュールするコードBallがすぐに呼び出さmovement()れます(確かに別のスレッドで)。これはすべて、割り当てられるMainにコンストラクターの途中で発生します。だからここの行で: Main.playermovement()

if(main.player.intersects(main.ball) && hitP == false){

...main.playerタイマースレッドが十分に速く開始する場合はまだnullであるため、main.player.intersects呼び出しは例外をスローします。(main.ballこれもnullですが、実際には問題は発生しません。それでも問題は発生します。)

学ぶべきいくつかの教訓:

  • コンストラクターでやりすぎないでください
  • 理想的には、この種の循環参照を作成しないようにするか、参照が必要な場合、実際の作業を開始する前にすべてが初期化されていることを確認してください
  • クラス名をより意味のあるものにします。プログラムへの単なるエントリポイントMainとしては問題ありませんが、タイプのオブジェクトを作成することは私には非常に疑わしいように思えます。とは何ですか?どのように説明しますか?MainMain
  • Ball継承を乱用しないでください-拡張する必要がある理由はありませんThread(あなたは言うが、あなたは自分でメソッドimplements Runnableを提供しません)run()Ball
  • またはとの比較を避けてくださいtrue-代わりにとの代わりにfalse書くif (foo)if (foo == true)if (!foo)if (foo == false)
  • 変数名を意味のあるものにします-前の私のコメントによると、呼び出されたRectangle変数playerと同じクラスのPlayer変数を呼び出すとp、問題が発生します
  • すべての変数をプライベートにし、必要に応じてプロパティを介して公開します。(本当に必要な場合を除いて、それらを公開しないでください
  • インデントは重要です-コードを適切にインデントすると、読みやすくなります
  • 言語の基本に本当に慣れるまでは、スレッド化を避けてください。難しいので、あらゆる種類の微妙な問題が発生する可能性があります。
于 2012-07-07T15:49:56.410 に答える
2

コードでは、18行目にnull以外の値をball.movement()割り当てる前に、17行目を呼び出します。main

于 2012-07-07T15:49:55.597 に答える
0

この行:player = new Rectangle(p.getX(), p.getY(), 10, 50);メイン行18ではb = new Ball(this);、メイン行15より前に移動する必要があります。そうしないと、移動を呼び出すときにプレーヤーがnullになります。

于 2012-07-07T15:52:52.077 に答える