4

昨日、第 14 回 Ludum Dare 48 時間ゲーム作成コンテストへのエントリーを終えたばかりで 、グラフィックに java2d を使用して Java で行うことにしました。

私は API に精通しておらず、多くのグラフィックス プログラミングも行っていませんが、私のゲームは非常に小さい (12 個程度の非常に小さな移動オブジェクトのみ) ため、素朴にプログラムできると思っていましたが、それでもパフォーマンスは発生しませんでした。問題。

言うまでもなく、私は間違っていました。ゲームはほとんどの場合問題なく動作しますが、画面上を動き回る「敵」が多すぎるか、解像度が高くなりすぎると、目に見えて遅くなり始めます.

パフォーマンスのボトルネックは画面描画機能であると判断しました。それらをコメントアウトすると、ゲームは非常に高速になります。

ここで私が間違っている可能性があることについて、誰かが私に注意を向けることができますか? (非常に短い) ソース コードはここにあり、そのほとんどはMainクラスであり、通常は内部ゲーム ループで呼び出されるdraw()関数が疑われます。

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

前もってありがとう、イド。

4

4 に答える 4

7

いくつかの観察ですが、どれもあまり役に立たないと思います。

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

フレームごとに色を再現します。これは、キャッシュしたいものの 1 つかもしれないし、そうでないかもしれません。ただし、色に定数を設定するとGCが台無しになる可能性が高く、後で色を再利用したいときに物事を簡単に維持できるとは思いません。

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

背景を描く必要はありません。背景色を設定して、親にすべて任せてください。

設計的なものとして、体は自分自身で描画を担当する必要があります。所有者は、それらを描画するのではなく、描画する必要があることを通知する必要があります。

体は毎回その状態を再現します。時々保存し、必要に応じて変更することを検討してください。drawCircleBody() で三角関数の計算に多くの時間を費やしている可能性があります。

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

SwingWorkerを使用して計算を行うことを検討してから、done() メソッドで状態を更新し、repaint() を呼び出して終了します。

これらはほんの一部です。何が機能し、何が機能しないかを実験して確認する必要があります。Java グラフィックスの描画を行ってからしばらく経ちました。

于 2009-04-20T16:15:23.010 に答える
6

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

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

これがあなたが見ている特定のパフォーマンスの問題を引き起こすかどうかはわかりませんが、潜在的な大きな問題として際立っています.

于 2009-04-20T16:02:57.563 に答える
6

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

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

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

...

void drawBody(Body body) 
{
    body.draw();
}
于 2009-04-20T16:03:12.633 に答える
4

ボトルネックが描画関数のどこにあるかを確認するためにプロファイリングを試みましたか?

見た目だけでは何とも言えませんが、なぜ drawPolygonBody でポリゴンの描画と塗りつぶしを両方行っているのか不思議です。
また、drawBoxBody では、drawRect() を呼び出すだけでなく、4 つの線を個別に描画しています。

于 2009-04-20T16:04:52.113 に答える