2013-02-16 64 views
1

我已經看了四周,似乎沒有人對我有任何答案。我有一個JPanel,當它運行時,我可以在其中添加/刪除標籤。問題是,每次我給它添加一個新標籤時,我都必須revalidate(),這樣新標籤纔會顯示出來。每一次,我都會產生一個非常煩人的閃爍,我的所有標籤都會在我的窗口頂部閃爍一毫秒,然後回到他們正在做的事情上。我唯一一次打電話revalidate()是在我添加一個標籤之後;我不改變塗裝方法或任何東西只有閃爍同時重新驗證JPanel

public void paintComponent(Graphics page) 
{ 
    super.paintComponent(page); 
} 

這樣我的網頁不會看起來不好。我真的可以在這方面使用一些幫助。我做了一個小行星遊戲,使用JFrame,JlabelJpanel遊戲;它工作的很好,但這種閃爍和組件「鬼鬼祟祟地重影到面板上方」是無法忍受的,我知道這是revalidate()方法。

+0

有關信息,我有一個代表船舶,子彈和小行星的標籤,我將它們添加到我的面板並將它們移除,因爲它們被用於拍攝或耗盡生命。使用add(component);並刪除(對手);然後我添加我重新驗證。 – Elton 2013-02-16 10:30:56

回答

2

使用標籤(或通常的GUI組件)來快速表示動畫,動態創建/移動的對象是不實際的。就像使用汽車從客廳開車到廚房一樣。

Swing組件帶有很多很好的功能,例如,他們可以確定他們需要的空間,佈局經理可以使用它自動將它們很好地放置。不幸的是,對於一款遊戲,你不需要所有的好東西,也不需要支付與之相關的處理開銷。通過擺動多平臺功能使問題變得更加複雜,其要求每個組件具有對等組件(對等組件處理將組件呈現爲活動外觀)。

要解決這個問題,您不會將單個遊戲對象表示爲揮杆組件。相反,你使用一個單獨的swing組件(通常是JPanel)作爲畫布來繪製你的遊戲對象。您只需定期爲該JPanel調用repaint()(例如,每秒30或60次)。當然,你會覆蓋JPanel上的paintComponent()來使用你自己的代碼來繪製所有的遊戲對象。

編輯:概述你怎麼做你自己的渲染

您需要決定如何組織你的遊戲相關的對象。一個很簡單的骨架看起來是這樣的(省略getter/setter方法):

public class GameObject { 
    public int x; 
    public int y; 
    public Image image; 
} 

在實踐中,這種類將有更多的成員(如控制對象如何動作行爲,併爲動畫也許有些州/計數器) 。對於每種可能的行爲(如船,小行星和子彈),它也可以是具體的子類的抽象。 GameObject的所有實例都在某種集合中進行管理,我假設您使用了一個List。

當實現在列表中把它歸結爲只是環路的paintComponent和渲染每個物體的圖像:

public void paintComponent(Graphics g) { 
    List<GameObject> list = ... // however you obtain it in your game 
    for (GameObject gobject : list) { 
     g.drawImage(gobject.image, gobject.x, gobject.y, (ImageObserver) null); 
    } 
} 

更復雜的遊戲,可以責令gameobjects獲得的遊戲對象如何相互重疊的控制。但原則上它非常簡單。

+0

唯一的問題,我不知道如何解決,因爲即時通訊NOB是每個東西,即子彈,小行星和船,有很多事情我不知道如何表示爲圖形。 – Elton 2013-02-16 19:03:12

+0

@Elton我添加了一些簡要說明,你如何創建自己的遊戲對象並渲染它們 – Durandal 2013-02-18 13:40:23

2

當我在擺動Swing組件時遇到問題,結果是併發問題。既然你正在做一個遊戲,這意味着你正在做動畫,它可能就是這種情況。

只能從AWT-EVENT thread修改Swing組件。請使用SwingUtilities.invokeLater或使用javax.swing.Timer做動畫。

2

作爲具體示例,Asteroids根本不閃爍。原因如下:

  • 它運行在event dispatch thread上。

  • 它使用JPanel,默認情況下是雙緩衝。

  • 它使用javax.swing.Timer來加速動畫,更新遊戲的模型actionPerformed()

  • 它重載paintComponent(),但可以安全地忽略super.paintComponent(),因爲動作偵聽器重新繪製整個面板。

  • 聽衆呼叫paintImmediately()以避免任何潛在的延遲;請替換repaint()以查看您的平臺是否有任何區別。

附錄:如在本counter-example所示,revalidate()不會引起閃爍。而不是替代標籤,更新標籤的圖標,如here所示。

2

您是否考慮過重複使用它們 - 即在不需要時使用setVisible(false)

不知道添加和刪除標籤是實現遊戲所需的最佳方式。 我個人很想自己管理繪圖。

+0

我想我會嘗試這個,我仍然是業餘編碼器,所以這對我來說似乎最簡單,謝謝你的反饋人。 – Elton 2013-02-16 19:00:10