簡體   English   中英

渲染到JPanel的最快方法是什么?

[英]What is the fastest way to Render to a JPanel?

所以我正在制作一些小型2D游戲引擎。 到目前為止它工作得很好,但渲染有點緊張,並且每1-2秒有一個滯后(幀凍結半秒)。 即使這不是一個交易破壞者,但它應該是一個煩惱,應該整理出來,我顯然對這是為什么有點好奇。

所以我當前渲染幀的方法是通過操縱某個JPanel的g2d對象:

(img是繪制的地圖。此方法是類的一部分,其中包含屏幕的寬度和高度以及相機的位置等所有信息。(因此PosX,PosY,寬度,高度取自對象的Instace)這被稱為)

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的當前動畫的BufferedImage(基本上是由於更改的所有內容;如播放器,Npcs,移動樹,太空飛船等)。

  3. 在最后兩件事之上繪制所有附加的UserInterface-Components。 (就像人物肖像一樣;沒有按鈕或任何可以互動的東西)

令我好奇的是,這不是一個程序使用如此多的CPU以至於無法跟上渲染的情況,因為程序具有與x附加的附加程序相同的延遲,因為沒有任何。 此程序使用我的CPU的大約5%(30fps)

所以問題必須在其他地方。 你有沒有想過優化它?

令我好奇的是,這不是一個程序使用如此多的CPU以至於無法跟上渲染的情況,因為程序具有與x附加的附加程序相同的延遲,因為沒有任何。 此程序使用我的CPU的大約5%(30fps)

  • Thread.sleep(int)引起的,你不應該使用Thread.sleep(int),只是在你要模擬一些長而昂貴的睡眠的情況下,否則要使用Timer

  • Thread.sleep(0) == zero miliseconds凍結當前JVM實例直到循環結束,沒有任何反應,直到這個循環被Thread.sleep()凍結,

  • Native OS中的延遲不低於16毫秒,25可能是一個限制,但要使用Timer而不是此值


g2d.drawImage

  • 今天的Java6/7

    1. 應覆蓋調用paintComponentJPanel
    2. 1。 paintComponent里面的代碼行應該是super.paintComponent() ==重置以前的所有繪畫,否則繪制累積

    3. Swing Timer在33-50毫秒的合理頻率下延遲或重新繪制

  • 它是關於在Swing中繪制以便在BufferedImage存儲當前快照的良好實踐,並且所有volatile變量或對象都可以存儲在List<Whatever> ,在paintComponent內部存儲到g2d.drawImage,並且其余的繪制將循環到准備好的array of ObjectList<Whatever>


更快地發布SSCCE ,簡短,可運行,可編譯,幾乎是問題

由於分配過多,您可能會遭受垃圾收集暫停。 有些方法在分配時看起來很可疑(例如“getCurrentlyActiveFrameAsBufferedImage”)。 使用VisualGC來檢查分配率,然后改進你的程序或嘗試獲得一個大的伊甸園。 大型二進制對象(如bitmaps / byte [])直接在OldSpace上分配,因此如果您創建了太多的二進制對象,則會觸發很多oldGC暫停。 如果是這種情況,調整伊甸園大小將無濟於事。

編輯:通過使用-verbose:GC選項運行程序,檢查“暫停”是否與GC相關

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM