[英]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);
}
}
}
這基本上是做什么的,它
根據用戶查看的位置繪制當前活動地圖的子圖像(某種方式中的攝像機視圖)
繪制所有附加的MabObjects的當前動畫的BufferedImage(基本上是由於更改的所有內容;如播放器,Npcs,移動樹,太空飛船等)。
在最后兩件事之上繪制所有附加的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
paintComponent
中JPanel
, 1。 paintComponent
里面的代碼行應該是super.paintComponent()
==重置以前的所有繪畫,否則繪制累積
Swing Timer在33-50毫秒的合理頻率下延遲或重新繪制
它是關於在Swing中繪制以便在BufferedImage
存儲當前快照的良好實踐,並且所有volatile變量或對象都可以存儲在List<Whatever>
,在paintComponent內部存儲到g2d.drawImage,並且其余的繪制將循環到准備好的array of Object
( List<Whatever>
)
更快地發布SSCCE ,簡短,可運行,可編譯,幾乎是問題
由於分配過多,您可能會遭受垃圾收集暫停。 有些方法在分配時看起來很可疑(例如“getCurrentlyActiveFrameAsBufferedImage”)。 使用VisualGC來檢查分配率,然后改進你的程序或嘗試獲得一個大的伊甸園。 大型二進制對象(如bitmaps / byte [])直接在OldSpace上分配,因此如果您創建了太多的二進制對象,則會觸發很多oldGC暫停。 如果是這種情況,調整伊甸園大小將無濟於事。
編輯:通過使用-verbose:GC選項運行程序,檢查“暫停”是否與GC相關
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.