0

私は自分のゲームに何かを追加しようとしました.1人のプレーヤーが弾丸に当たった場合、彼の健康状態は低下します. 問題は、これをチェックしているときに、CPU が 100% で、すべてが非常に遅いことです。これは問題です。ここに私が使用しているスレッドがあります:

 package Graphics;

 import java.util.logging.Level;
 import java.util.logging.Logger;


 public class BulletCollision implements Runnable {
     Player1 player1 = new Player1();
     Player2 player2 = new Player2();

     public Thread checkBulletCollision = new Thread(this);

     public void checkPlayerBulletCollide() {
         if (player2.getBulletX() > player1.getX() && 
             player2.getBulletX() < player1.getX() - 50) {
            player2.decHealth(50);
         }
     }

     @Override
     public void run() {
         while(true) {
             checkPlayerBulletCollide();
             try {
                 checkBulletCollision.sleep(100);
             } catch (InterruptedException ex) {
                 Logger.getLogger(BulletCollision.class.getName()).log(
                     Level.SEVERE, null, ex);
             }
         }
     }
  }

ここに問題があると確信しています。コンパイルまたは実行時にエラーはありません。誰かがそれを助けることができれば、それは素晴らしいことです! このクラスを作成しただけなので、コードは完璧ではありません。私はこれを修正するために多くのことを試みました.JFrameのみを表示するDisplayクラスでThreads start()メソッドが呼び出されています. 私は以前、クラス化されたプレーヤーの 1 つで start メソッドを使用していました。

4

2 に答える 2

0

私の意見では、この場合、別のスレッドでこのブロック フリー ランニングを使用することは正しくありません。

while(true) {
    checkPlayerBulletCollide();
    try {
        checkBulletCollision.sleep(100);
    } catch (InterruptedException ex) {
        Logger.getLogger(BulletCollision.class.getName()).log(Level.SEVERE, null, ex);
    }
}

これはフレームごとに 1 回だけ行いcheckPlayerBulletCollide()、描画ロジックから を呼び出します。

またThread.sleep()、これは静的関数であるため、特定の Thread インスタンスを別の Thread からスリープ状態にすることはできません。Threac はそれ自体をスリープ状態にすることができます...

EDITきれいにコーディングしたい場合 (これは非常に優れています)、Java 1.5 以降のロック機構を使用することをお勧めします。

これは (それぞれ 1 つの弾丸を持つ 2 人のユーザーの現在のコンテキストでは) 軽量ではありませんが、BlockingQueueを使用します。チェック スレッドは queue.take() を発行する必要がありますが、実際の Integer 値は重要ではありません (後で弾丸やプレイヤーが増えると、どの弾丸とどのユーザーをチェックするかを指定するオブジェクトをキューに入れることができます。 ..)。描画ロジック、または描画を制御するロジックは、queue.offer(0) を実行します。チェックスレッドは次のようになります。

public class BulletCollision implements Runnable{

    Player1 player1 = new Player1();
    Player2 player2 = new Player2();

    public BlockingQueue<Integer> checkQueue = new LinkedBlockingQueue<Integer>();
    public void checkPlayerBulletCollide() {
        if(player2.getBulletX() > player1.getX() && player2.getBulletX() < player1.getX() -50) {
            player2.decHealth(50);

        }
    }

    @Override
    public void run() {
        while(true) {
            try {
                queue.take();
                checkPlayerBulletCollide();
            } catch (InterruptedException ex) {
                Logger.getLogger(BulletCollision.class.getName()).log(Level.SEVERE, null, ex);
                break; //I'd put this here. If we were interrupted, the hread should stop gracefully.
            }
        }
    }
}

また、フレームの描画が完了したら、queue.offer(0);

于 2012-10-27T07:51:21.670 に答える
0

問題はこのコードにはありません。1 つまたは 2 つの欠陥がありますが、このコードには遅延が発生するものは何もありません... 私が知る限り。


FWIW、欠陥は次のとおりです。

1) これは悪いスタイルです:

  checkBulletCollision.sleep(100);

このThread.sleepメソッドは静的であるため、次のように呼び出す必要があります。

  Thread.sleep(100);

2) スレッドrun()メソッドは、割り込みを受け取った場合に戻る必要があります。あなたはそれを継続するようにコーディングしました...それはそれを中断する目的を無効にします.

于 2012-10-27T08:22:44.700 に答える