1

だから私はある種の小さな 2D - ゲームエンジンを作っています。これまでのところ問題なく動作していますが、レンダリングは少しぎくしゃくしており、1 ~ 2 秒ごとに遅延があります (フレームが 0.5 秒フリーズします)。これはほとんど契約を破るものではありませんが、整理しなければならない煩わしさであり、私はこれがなぜなのか明らかに興味があります.

したがって、フレームをレンダリングする現在の方法は、特定の JPanel の g2d オブジェクトを操作することです。

(img は描画されるマップです。このメソッドは、画面の幅と高さ、カメラの位置などのすべての情報を持つクラスの一部です。(したがって、PosX、PosY、幅、高さはオブジェクトのインスタンスから取得されます)これが呼び出されます)

public void DrawByManipulatedMapSubimage(BufferedImage img, Graphics2D g2d)
{
    if (isActive)
    {
        BufferedImage img2 = img.getSubimage(PosX, PosY, width, height); 
        g2d.drawImage(img2,0,0,null);
        List<MapObject> MapObjects = Map.getObjectInformation();
        List<UiComponent> UC = this.UI.getUiComponents();

        int l = this.Map.getObjectInformation().size();

        for (int i = 0; i < l; i++)
        {
            MapObject MO = MapObjects.get(i);
            int MOX = MO.getPosX();
            int MOY = MO.getPosY();
            BufferedImage MOB = MO.getCurrentAnimation().getCurrentlyActiveFrameAsBufferedImage();

            g2d.drawImage(MOB, MOX - PosX, MOY - PosY, null);
        }

        for (int i = 0; i < UC.size(); i++)
        {
            UiComponent CC = UC.get(i);
            if (CC.isVisible())
            {
                Point P = CC.getPosition();
                int x = P.x;
                int y = P.y;
                g2d.drawImage(CC.getImg(),x,y,null);
            } 
        }
        try 
        {
            Thread.sleep(0);
        } 
        catch (InterruptedException ex) 
        {
            Logger.getLogger(Viewport.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
}

これが基本的に行うことは、

  1. ユーザーがどこから見ているかに基づいて、現在アクティブなマップのサブイメージを描画します (ある意味でのカメラ ビュー)

  2. その上に、アタッチされたすべての MabObjects (基本的に変更されるすべてのもの。プレーヤー、Npcs、動く木、宇宙船など) の Current Animation の BufferedImage を描画します。

  3. 最後の 2 つのものの上に、アタッチされたすべての UserInterface-Components を描画します。(たとえば、キャラクターのポートレートのようなもの。ボタンや操作可能なものはありません)

私が興味を持っているのは、これは、プログラムが x を追加した場合と同じように実行時に遅延が発生するため、プログラムがレンダリングに追いつくことができないほど多くの CPU を使用している場合ではないということです。どれか。また、このプログラムは CPU の約 5% を使用します (30fps で)

したがって、問題は別の場所にある必要があります。最適化するアイデアはありますか?

4

2 に答える 2

3

私が興味を持っているのは、これは、プログラムが x を追加した場合と同じように実行時に遅延が発生するため、プログラムがレンダリングに追いつくことができないほど多くの CPU を使用している場合ではないということです。どれか。また、このプログラムは CPU の約 5% を使用します (30fps で)

  • が原因でThread.sleep(int)、Thread.sleep(int) を使用しないでください。長くてコストのかかるスリープをシミュレートする場合にのみ使用してください。それ以外の場合は、Timer を使用してください。

  • Thread.sleep(0)==zero milisecondsループが終了するまで現在の JVM インスタンスをフリーズします。このループがフリーズするまで何も起こりませんThread.sleep()

  • ネイティブ OS のレイテンシは 16 ミリ秒未満ではありません。25 ミリ秒が限界かもしれませんが、代わりにこの値でタイマーを使用するには


g2d.drawImage

  • 今日のためにJava6/7

    1. でオーバーライドpaintComponentして呼び出す必要がありますJPanel
    2. 1位。内部のコード行paintComponentは == 以前のすべてのペイントをリセットする必要がありますsuper.paintComponent()。そうしないと、ペイントが累積されます

    3. Swing Timerによって 33 ~ 50 ミリ秒の適切な頻度で遅延または再描画されます

  • 現在のスナップショットを に格納するための Swing でのペイントの適切な実践について説明しBufferedImageます。また、すべての揮発性変数またはオブジェクトを に格納しList<Whatever>、paintComponent 内で g2d.drawImage に格納し、ペイントの残りの部分を準備済みarray of Objects( List<Whatever>)内でループすることができます。


より良いヘルプのために、SSCCE、短く、実行可能で、コンパイル可能で、もうすぐ問題を投稿してください

于 2013-11-02T13:05:08.807 に答える