2014-02-08 62 views
4

我對遊戲開發比較陌生。我一直在開發遊戲並學習2-3個月的遊戲開發。我使用Java。Java:使用Swing編程遊戲

我一直使用Swing作爲我的圖形(也就是說,整個遊戲顯示在JPanel上,使用Graphics2D對象)。到目前爲止,我沒有遇到任何麻煩。

最近,我在最近的項目中遇到了一個問題。某些方法在一致的時間間隔內調用有問題(有時它每15-16毫秒運行一次,因爲它應該,有時它會開始每3000(!)毫秒運行一次)。

我做了一些令人沮喪的調試和一些研究,並發現這種情況發生的原因可能是因爲我沒有處理Swing和線程的權利。

我的entrie遊戲循環在線程的run()方法內運行(它不是EDT)。所以我一直在修改EDT之外的Swing元素。顯然這必然會造成問題。

當我發現這是問題是,我想:

「嘿,我只是爲了運行EDT內gameloop使用SwingUtilities.invokeLater()!」

但後來我想起,只是因爲它的「禁止」,以操縱搖擺元素的EDT之外,這也是有問題的操作裏面從非Swing對象EDT我認爲...這是否正確?)。

如果是這樣,那麼我不知道如何使用Swing 開發Java遊戲而不會遇到奇怪的問題

我的問題是:

我如何開發遊戲安全,使用搖擺?爲避免涉及Swing和線程的問題,我會嚴格執行哪些準則?每個使用Swing的遊戲開發者的任何說明都應該知道?

這對我來說很重要,因爲我真的想用Java進行遊戲開發,但如果我不明白這一點,我總是會遇到奇怪的問題,不會能夠進步。

謝謝您的幫助

+0

根據我的經驗,使用單一的非EDT線程工作。 – Darkhogg

+0

@Darkhogg怎麼回事?我雖然從EDT外部操縱一個JPanel應該會導致問題。 –

+0

Swing是一個帶有按鈕和複選框等的小部件庫...它真的適用於數據+生產力應用程序。對於遊戲,你只需要一個OpenGL緩衝區的像素緩衝區來繪製。你有沒有考慮過lwjgl或jogl?即使是2D遊戲? – user2684301

回答

3

只要你不修改任何東西,但在面板上繪製的圖形,你應該行的大部分時間。就像單個非EDT線程在大多數時間工作。只要你不添加或刪除任何gui元素,不要調整任何東西,不要隱藏任何東西等,Swing不會調整其內部細節,足以導致線程和EDT之間的競爭狀態 - 大多數的時間。

即使用戶在非EDT代碼繪製時最小化面板的情況也不會導致崩潰 - 面板可能會丟棄其舊圖形上下文並開始使用新的圖形上下文,但舊的上下文將保持有效,直到您釋放它(這與C++不同,其中delete立即使對象無效,當不同線程仍使用本地指針時會導致崩潰)。

問題是,如果您使用「我還沒有看到出現問題的情況,總是爲我工作」的方法,您將依賴未定義的行爲,並且您的代碼可能開始崩潰儘快更新您的JVM。

您可以做的最好的事情是在EDT線程上設置您的GUI,在不同線程上運行您的遊戲邏輯,每20毫秒在面板上定時器調用repaint()(或任何您希望幀速率爲)。然後,有一個類對象,它包含顯示當前遊戲狀態所需的所有內容。在​​代碼塊內,讓面板的paint()生成它自己的對象副本,並在主線程調用任何遊戲需要時使用副本paint()。當然,主線程應該使用相同的​​來寫入類對象。這樣,您可以在線程之間獲得最大可能的分離。只要在EDT上運行你的整個遊戲線程可能不會這樣做,因爲任何你的遊戲可能需要一段時間都會導致UI凍結。而任何需要大量UI資源的東西都會影響你的遊戲邏輯。

順便說一句,你確定你最初的問題(長時間拖延時間,但不是總是)不是垃圾收集的結果?我已經看過幾次了;如果你不使用並行垃圾收集器,GC可能會運行幾十秒鐘,並阻止其他任何事情。