2010-03-03 47 views
1

作爲任務的一部分,我正在重新創建「塞爾達傳說與過去的鏈接」。爲遊戲繪製背景圖像的Java優化

我得到了以下問題,遊戲世界是一個BufferedImage,其中我subImage()是玩家當前位置所需的部分。遊戲可以運行,但使用CPU的80%/ 110%。個人資料顯示,罪魁禍首是圖像的繪製。

所以我想我把背景放在播放器,敵人等JPanel單獨的JPanel中。 將它們渲染爲互相重疊(JLayeredPane),並重新繪製背景面板的次數要少得多。

但我該如何做到這一點我該如何告訴擺動畫一個面板x秒和其他y次?如果你有更好的方式讓我知道。

下面是我在此刻得到了:

public class Main extends JFrame 
{ 
    private ZeldaGame game = new ZeldaGame(); 
    private View view = new View(game); 
    private BackgroundView bckView = new BackgroundView(game); 
    private Controller ctl = new Controller(game, view, bckView, this); 

    public Main() 
    { 
     setLayout(null); 

     view.setBounds(0, 0, game.getWidth(), game.getHeight()); 
     bckView.setBounds(0, 0, game.getWidth(), game.getHeight()); 

     JLayeredPane pane = new JLayeredPane(); 
     pane.add(bckView, 1); 
     pane.add(view, 0); 

     setLayeredPane(pane); 

     setSize(game.getWidth(), game.getHeight()); 
     setResizable(false); 
     setLocationRelativeTo(null); 
     setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 

     setVisible(true); 
    } 

    public static void main(String[] args) 
    { 
     new Main(); 
    } 
} 

謝謝。

回答

4

由於幀緩衝器的工作方式,渲染時間不同,實際上是不可能的 - 結果會是令人討厭的閃爍負載。您需要做的是使用Canvas而不是JPanelJLayeredPane,您可以覆蓋畫布的paint()方法或使用bi.getGraphics(),並按照正確的順序使用這些方法中的任一方法來循環背景和循環中的字符。我建議使用像GTGE這樣的精簡引擎,它將從所有優化的細節中抽象出來。您認真使用的這些高級別組件不是爲遊戲設計的,您根本不應該使用它們。

+0

謝謝我發現一篇文章感謝您對bi.getGraphics的建議,請參閱我的答案。 GTGE聽起來不錯,但我自己也是爲了體驗而做的。無論如何它都是一項任務。 PS JCanvas不是Java的一部分,所以你的意思是Canvas或JCanvas項目? – MrHus

+0

GTGE現在是開源的,看看裏面(http://code.google.com/p/gtge) - 這是我學習了很多有效的Java2D遊戲技術的地方,加上*非常接近於什麼如果你從頭開始做,你會做的:)而且,對不起,我的意思是Canvas而不是JCanvas(oops)。 –

0

好吧,我發現我的方式錯誤。我使用被動渲染,而我應該使用active rendering。主動渲染基本上通過調用setIgnoreRepaint(true)來關閉自動重繪。在框架上,並自己做循環。

而作爲額外的獎勵,我不需要使用JPanels。

+0

即使被動渲染也沒關係,有時可以更高效。基本上,使用被動渲染你所要做的就是覆蓋Canvas的paint(Graphics g)方法,並允許它更新視圖。然而,由於遊戲組織,結構的原因,並不總是有可能在這裏放置視圖渲染代碼(也許你的代碼結構(可能不是模型 - 視圖 - 控制器)限制你在每次更新結束時渲染)。但基本上,使用被動渲染,無論如何都可以使畫布無效,並且會意識到它需要重新繪製。 –