2009-04-20 11 views
4

昨日、14回のLudum Dare 48時間ゲームでmy entryを終了しました。そして、java2dを使用してグラフィックスを行うことにしました。シンプルなJava2Dアプリケーションの面倒なパフォーマンス

私はAPIに精通しておらず、多くのグラフィックプログラミングを行っていませんが、私のゲームは非常に小さく(わずかに移動するものが十数個しかありません)、パフォーマンスに問題はありません。

言うまでもなく、私は間違っていました。ゲームは大部分の時間は大丈夫ですが、画面上で動き回る「敵」が多すぎたり、解像度が高すぎると視覚的に遅くなり始めます。

私は画面の描画機能としてパフォーマンスのボトルネックを判断しましたが、コメントアウトされているときは非常に高速です。

誰かが私にここで間違っているかもしれないことに頭を上げてもらえますか? (非常に短い)ソースコードはhereであり、そのほとんどはMainクラスであり、通常の疑いはinner game loopで呼び出されるdraw()関数です。

私は既にBufferStrategyを使用して画面を更新しています。間違っていない限り、問題はないはずです。

ありがとうございます。 Ido。

+0

+1このトピックに関する多くの関連する質問があるようですが、これが新しい情報を生成するかどうか確認することになります。 –

答えて

7

私はいくつかの観察は、私はそれらのどれも多くを助けるとは思わないが。

主なことは、あなたがAWTスレッドからペイントしていることです。 paintComponent()をオーバーライドし、代わりにオブジェクトに対してrepaint()を呼び出します。これはそうでなければあらゆる種類の問題を引き起こす可能性があります。

フレームごとに色を再作成します。これは、キャッシュしたいものの1つである場合とそうでない場合があります。私はあなたの色のための定数を持つことは、GCingを台無しにする可能性が高いと思うが、後で色を再利用したいときには、物事を簡単に保つことが容易になります。

フレームごとにウィンドウ全体を再描画します。変更されたセクションを再描画するだけで済みます。

背景を描画する必要はありません。背景の色を設定し、親がすべてを世話するようにします。

デザインとして、身体は自分自身を描くことを担当する必要があります。彼らの所有者は、それらを描くのではなく描かなければならないことを彼らに知らせなければならない。

ボディは毎回状態を再現します。彼らは時々それを格納し、必要に応じてそれらを変更することを検討してください。あなたは、drawCircleBody()でtrig計算を行うのに多くの時間を費やしているかもしれません。

whileループでスリープを使用するのではなく、タイマーを設定することが考えられます。これにより、より一貫したフレームレートが得られますが、実際に義務を果たすことができるようにするか、締め切りが間に合わない場合は複数のフレームを1つにまとめる必要があります。

SwingWorkerを使用して計算を行い、done()メソッドの状態を更新し、repaint()を呼び出して終了することを検討してください。

これはほんの数個の例です。何が効果的で何が効果がないかを実験する必要があります。私がJavaのグラフィックス描画をしてからしばらくしています。

+0

これは答えです、私は+4があったといいですね! –

+0

詳細な回答ありがとうございます。 第1の点については、例えば、 JFrameではなくJPanelを呼び出し、paintComponent()をオーバーライドしますか? JFrameには私が上書きできるような機能はないからです。 私のアプリケーションの規模を1 cpu/core以上にするというボーナスもあるでしょうか?そのため、計算作業の大半はGUIとは別のスレッドで行われるため、 –

+0

はい、おそらくJPanelです。実際のウィンドウの振る舞いを変更する必要がある場合にのみ、JFrameを拡張する必要があります。実際にはコンテンツペイン(JPanelに設定することができます)を描画します。 スケーリングに関しては、いくつかの作業が順番に行われなければならないので、スケールすることはできません。特に、各フレームは逐次的に行われなければならない。しかし、将来のJVMは実際にあなたのためにいくつかのマルチコア最適化を行うことができます。 – James

6

シングルスレッドのルールに従っていないあなたのコード:

http://java.sun.com/products/jfc/tsc/articles/threads/threads1.html

私は、これはあなたが見ている特定のパフォーマンスの問題が発生するかどうかわからないんだけど、それは大きな可能性として際立っています問題、イモ。

+0

はい、実際には、スレッドの数が増えるほどパフォーマンスや奇妙な視覚効果に大きな問題が発生し、問題になる可能性が非常に高いです。 –

+0

Jamesさんが言ったようなGuiの糸の外の絵を意味するのですか、それとも別のものですか? –

6

まあ、draw()関数を簡単に見てみると、(特にdrawPolygonBodyの)多くの新しいオブジェクトを宣言しているようです。毎回新しいオブジェクトを宣言するのではなく、オブジェクトを再利用してみてください。

EDIT:instanceofにオーバーヘッドがあります。 Bodyを描画するdraw(Graphics g)関数を持つようにBodyを拡張することをお勧めします。例えば:

public class Circle extends Body 
{ 
    // override 
    public void draw(Graphics g) 
    { 
     ... 
    } 
} 

... 

void drawBody(Body body) 
{ 
    body.draw(); 
} 
4

は、あなたはそれがボトルネックになっている描画機能でを見るために、プロファイリングしたことがありますか?

私はdrawPolygonBodyでポリゴンを描画しているのはなぜですか?
また、drawBoxBodyでは、drawRect()を呼び出すのではなく、4つの線を別々に描画しています。

+0

私はあなたが正しいと思う、私は多角形を埋める場合もそれを描画する必要はありません。 drawBoxBodyでは最初にそのようにしましたが、いくつかの問題が発生して元に戻りましたが、もう一度見ていきます。 –

関連する問題