0

ですから、私が作成しているゲームでは、最初にゲームをプレイしたときはうまく動作するので、gameLoopで何か問題が発生したことに気付きましたが、2回目以降は、約半分の速度で遅くなります。ゲームを最小化しても(gameLoopを停止し、再度起動すると元に戻るため)、gameLoopコードは次のとおりです。

public void gameLoop(){

        new Thread(){
            public void run() {
                while(gameRunning){
                    try {
                        Thread.sleep(1000/60);
                    } catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                    if (tutorial){
                        updateBullet();
                        updatePlayer();
                        repaint();
                    } else {
                        updateEnemies();
                        updateBullet();
                        createEnemies();
                        updateParticles();
                        updatePlayer();
                        repaint();
                    }

                }
                repaint();
            }
        }.start();
}

init()で初めて開始します

gameLoop();

そして、私も持っています:

public void stop(){
    bg.stop();
    gameRunning = false;
}
public void start(){
    bg.start();
    gameRunning = true;
    gameLoop();

}

そして最後に、playerUpdateはループを停止します(プレーヤー内のスレッドは、プレーヤーが死んだ後にいくつかの効果を終了できるようにするためのものです):

 public void updatePlayer(){
    if (player.isMovingLeft){
        player.x-=3;
    }
    if (player.isMovingRight){
        player.x+=3;
    }
    for (int j=0; j < enemies.size(); j++){
        if (player.isAlive){
            if (enemies.get(j).x+19 > player.x && enemies.get(j).x < player.x+40 && enemies.get(j).y > player.y  && enemies.get(j).y < player.y+40) {
                enemies.remove(j);
                j--;
                explode.setFramePosition(0);
                explode.start();
                for (int k = 0; k <21; k++){
                    addParticle(player.x+20,player.y+20,2);
                }
                new Thread(){
                    public void run() {
                        try {
                            Thread.sleep(2000);
                            gameRunning = false;
                        } catch (InterruptedException e) {
                            // TODO Auto-generated catch block
                            e.printStackTrace();
                        }
                    }
                }.start();

                player.isAlive = false;
                break;

            }
        }
    }
}

そして、keyPressedイベントで再起動されます。

if (!gameRunning){
        if (arg0.getKeyCode() == KeyEvent.VK_ENTER){
            enemies.clear();
            bullets.clear();
            particles.clear();
            score = 0;
            player.x = 200;
            player.isMovingLeft = false;
            player.isMovingRight = false;
            player.isAlive = (true);

            gameRunning = true;
            gameLoop();
        }
    }

では、ループを停止して再開するたびに、ループが半分の速度で実行されるのはなぜですか?ありがとう!

4

2 に答える 2

1

ゲームループごとに新しいスレッドを開始しているようです。これは、ゲームループが実行されるたびに、JavaVMが処理する別のスレッドがあることを意味します。これは非常に非効率的です。最終的には1000のスレッドが実行され、大きな遅延が発生するためです。そこにスレッド化せずにコードを書き直す方法はありますか?

また、これは何をすることになっていますか?

                try {
                    Thread.sleep(1000/60);
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }

なぜあなたは1000/60をするのですか?A:16だけを使用しないのはなぜですか?B:ここで何か他のことを意味しているようですが、どうでしょうか。

start()また、あなたのメソッドとメソッドで参照しているbg変数は何stop()ですか?

于 2012-08-24T15:45:17.950 に答える
0

gameRunningブール値を使用してスレッドを停止しようとしているようです。これが揮発性でない場合、ゲームループは、それをfalseに設定するGUIスレッドからの変更に気付かず、永久に実行される可能性があります。揮発性であっても、ゲームスレッドが停止コマンドに気付く前にstartが再度呼び出されると、競合状態になります。

代わりに、作成されたスレッドへの参照を保存し、stopメソッドで中断する必要があります。

また、すべての更新メソッドは、paintメソッドに関してスレッドセーフです。updatePlayerはスレッドセーフに見えません。また、paintがいつ呼び出されるかわからないため、updateメソッドと同時に発生する可能性があります。paintメソッドが共有データに書き込まない場合でも、メモリバリアがないため、一貫性のないデータが表示される可能性があります。

非常に遅く、マルチスレッドが必要な場合を除いて、GUIスレッドですべての更新を行うことをお勧めします。Swingからのタイマーを使用して更新ロジックを開始することを検討してください。

于 2012-08-24T18:48:55.403 に答える