2

私はSwingにいくつかの問題があり、キャラクターをアニメーション化します。キーリスナーを持つJFrameがあり、ユーザーがヒットすると、ここでJPanelメソッドが呼び出されます

for(int i=1;i<4;i++)
{           
    pY+=16;
    g.drawImage(perso,pX,pY,pX+50,pY+50,0+50*i,0,50+50*i,50,this 
    this.repaint();                 
}

これは私のキャラクターをアニメーション化しますが、非常に高速で物を見ることができます。アニメーションを表示するにはどうすればよいですか?

4

3 に答える 3

7

答えはすでにJonasによって与えられています(Swingタイマーを使用)が、アニメーションが表示されない理由と、タイマーがこの問題の最善の解決策である理由を説明するのに役立つ場合があります。

別の塗り直しが表示されないのはなぜですか

あなたが呼ぶときJComponent#repaintJComponentは塗り直されません。代わりに、特定のコンポーネントを再描画する非同期要求がEDTでスケジュールされます。多くの呼び出しを呼び出す場合repaint、Swingはそれらの要求をグループ化し、コンポーネントを1回だけ再描画することを決定する場合があります。

Oracleのドキュメントでこれに関する公式のリファレンスをすぐに見つけられませんでした(Swingのペイントの記事では言及されていないようです)。私がこれを見つけた唯一の場所はこの記事のメモにありましたが、これはどこかに文書化されていると確信しています。

なぜTimer最良のソリューションを使用しているのですか

アニメーションの場合、基本的に次のように言います。

私のキャラクターはミリ秒単位xでピクセルを移動する必要がありますy

そして、できれば、画面上で滑らかなアニメーションを作成したいので、かなり頻繁に再描画する必要があります。あなたがそれを覚えているなら

  • Swingコンポーネントとのすべての対話は、EDTで行われる必要があります(イベントディスパッチスレッド。詳細については、Swingでの同時実行の記事を参照してください)。
  • EDTをブロックしないでください。UIがフリーズします。つまり、再ペイントが完了するまでEDTで「待機」できないか、再ペイントが発生しません。
  • 再描画リクエストはグループ化できるため、再描画時間を呼び出しても、メソッドが時間も呼び出されるとxは限りません。paintx

この制限を克服するための解決策は、を使用することTimerです。同じ例(画面上のキャラクターの移動)では、を使用しTimerてキャラクターの位置を更新し、再描画をスケジュールできます。コードはEDTでトリガーされるためTimer、Swingスレッドルールに違反することはありません。

次に、コンポーネントのpaintComponentメソッドで、現在の場所にキャラクターをペイントします。これは、前の呼び出しと現在の呼び出しTimerの間にトリガーされた回数に応じて、「前の場所+ 1」、または「前の場所+2」(または...)の場合があります。これにより、キャラクターの移動速度がシステムに依存しなくなります。アニメーションの滑らかさだけがシステムに依存します(グループ化される再描画リクエストの数など)。paintpaint

JonasがすでにリンクしているSwingチュートリアルには、より多くの情報が含まれていますTimer

于 2012-06-18T19:53:31.843 に答える
3
  1. 拡張せず、ローカル変数としてJFrame作成JFrame

  2. 使わないで代わりにKeyListener使うKeyBindings

  3. に直接ペイントせず、またはJFrameに使用drawImage()します。JLabelJComponent/JPanel

  4. これは私のキャラクターをアニメーション化しますが、非常に高速で物を見ることができます。アニメーションを表示するにはどうすればよいですか?

の別の問題KeyListenerです。2 つの間の遅延を設定する必要があります。KeyEvents

于 2012-06-18T18:48:53.617 に答える
2

Swing Timer を使用して、定期的にアニメーションを更新できます。スイングタイマーの使い方を見る

于 2012-06-18T18:41:06.253 に答える