1

Swing で作成された GUI を備えたプログラム、ゲームがあります。

GUI は、JFrame を継承し、カードとして複数の JPanel を持つ CardLayout を持つ JPanel を保持する独自のクラスで構成されています。

これらのパネルの 1 つには、ゲームを開始するボタンがあり、ゲーム ビューはカードの 1 つにあります (JPanel を継承する独自のクラスを持つビュー オブジェクトは、JFrame のコンストラクターでカードに追加されます)。 .

今プロローグ:

JButton を押すので、Event Dispatch Thread にジャンプして actionPerformed メソッドを実行します。

このメソッドでは、最初にビュー パネルを保持するカードをめくってから、プレイするレベルとゲーム エンジン (レベルに従ってインスタンス化されます) をインスタンス化します。次に、ビュー オブジェクトで repaint を呼び出し (アプリケーション ウィンドウでゲームがペイントされることになります)、ゲーム エンジン オブジェクトを呼び出してゲーム ループを開始します。

私の問題は次のとおりです。

ボタンを押すと、ゲーム エンジンが正常に動作し始めます (コンソールの出力から確認できます) が、GUI がフリーズし、更新されずにゲーム ビューが表示されません。ゲーム ループを開始するコードのスニペットを削除すると、ゲーム ビューが画面に正常に表示されますが、ゲーム ループが開始されていないため、何も動きません。

したがって、Java ではすべてが記述された順序で行われるわけではないため、actionperformed メソッド内の他の操作が完了する前にゲーム ループの実行が開始されると推測しました。

actionperformed メソッドからの関連するスニペットは次のとおりです。

if (e.getSource() == aloitusnappula) {

CardLayout kortti = (CardLayout)valikopaneeli.getLayout(); Kentta kentta = new Kentta("testikentta.txt"); kortti.show(valikopaneeli、「ペリ」); Peli.this.pack(); Peli.this.setVisible(真); aloita(ケンタ); }

aloita(kentta) メソッドのスニペットを次に示します。

public void aloita(Kentta kentta) {
 moottori = new Pelimoottori(Peli.this, kentta);
 nakyma.repaint();
 moottori.peliLooppi();
}

ここで、Pelimoottori = ゲーム エンジン クラス nakyma = ビュー オブジェクト peliLooppi() = ゲーム ループを開始するゲーム エンジン クラスのメソッド

aloita メソッドから moottori.peliLooppi() 呼び出しを削除すると、ゲーム ビューは正常に表示されます。

私はいくつかの答えをグーグルで検索しようとしましたが、私が得た最も遠いものは、どういうわけかSwingWorkerでそれを行うことですが、どういうわけか私がやりたいことをする良い方法のようには思えません.

助言がありますか?

4

2 に答える 2

1

edt 内でエンジン ループを開始するとします。もしそうなら、それは悪いです。

edt から別のスレッドを呼び出し、この新しいスレッドからエンジンを管理します。GUI の更新については、SwingUtilities.invokeLaterで edt を呼び出します。

または、SwingWorkerを使用してください。

Swingでの長期的な仕事に関する優れた英語のドキュメントを読むには、Concurrency in Swingを参照してください。Thread.sleep を使用しないでください。

于 2011-01-11T22:07:00.533 に答える
1

ゲームループを開始するコードのスニペットを削除すると、ゲームビューが画面に正常に表示されます

おそらく、Thread.sleep で while ループを使用しているようです。

より良いアプローチは、Swing Timerを使用してゲームの「ループ」をスケジュールすることです。

于 2011-01-11T22:37:03.233 に答える