天天看點

《Java 2D遊戲程式設計入門》—— 1.3 使用主動渲染

本節書摘來異步社群《java 2d遊戲程式設計入門》一書中的第1章,第1.3節,作者:【美】timothy wright(萊特),更多章節内容可以通路雲栖社群“異步社群”公衆号檢視。

前面的示例使用了一種叫做被動渲染(passive rendering)的技術。該應用程式在paint()方法中重新繪制自身,但是,由swing庫來決定什麼時候調用該方法。事件分派線程處理swing元件的渲染,而這并不由你來控制。盡管這對于正常應用程式來說很好,但對于遊戲不推薦這麼做。

要處理渲染,可以使用bufferstrategy類,但這需要對應用程式的結構做一些修改。這将允許應用程式把渲染代碼放在一個單獨的線程中,并且由整個程序來控制。

把遊戲代碼放在paint()方法之外,通常有3個理由。首先,在paint()方法中不應該有任何需要很長的執行時間或阻塞時間的代碼,因為這會阻止gui接受繪制事件。其次,要使用全屏獨占模式的話,渲染代碼需要在一個不同的線程中。最後,并且也是最重要的原因,當從頭開始處理繪制的時候,渲染代碼會更快一些。為了利用主動渲染的好處,不管是在視窗還是全屏模式下,都要建立一個定制的渲染線程。

正如你在第一個示例中看到的那樣,沒有什麼實用的方法将繪制代碼放入到一個jpanel繪制方法中,卻從定制的渲染線程調用該代碼。為了在一個定制的循環中處理繪制,我們可以使用bufferstrategy類。這個類用來執行雙緩沖(double-buffering)和頁交換模式(page-flipping)。

如圖1.2所示,雙緩沖用來避免在進行繪制的時候,看到一幅圖像的實際繪制過程。在記憶體中繪制圖像,然後一次性複制整個圖像,這樣,繪制的過程就不會被看到。

可以在全屏獨占模式下使用的頁交換模式也采用了同樣的思路,但是,它保持了兩個離屏圖像,并且直接從一個緩沖到另一個緩沖交換視訊指針。通過這種方式,沒有繪制到螢幕上的那個圖像,可以被清除并重繪。當繪制完成的時候,指針再次交換,将新的圖像繪制到螢幕上,如圖1.3所示。

通過使用bufferstrategy類,程式是全屏模式并使用頁交換模式,還是程式是視窗模式并使用雙緩沖,都無關緊要了——這些技術都會在幕後處理。為了在一個渲染循環中使用bufferstrategy,用getdrawgraphics()方法建立一個圖形對象。這個圖形對象将會繪制到離屏表面。一旦這個圖形對象變得可用,它的使用方法完全像傳入到jpanel類的paint()方法中的圖形對象一樣。

《Java 2D遊戲程式設計入門》—— 1.3 使用主動渲染

調用contentslost()來確定離屏表面可用,這一點也是很重要的。一些作業系統允許使用者通過alt-tab方式離開全屏應用程式,這會導緻離屏圖像變得不可用。

show()方法執行雙緩沖/圖像複制或者頁交換模式/指針交換來顯示圖像。注意,這段代碼包含在try/finally語句塊中。和其他繪制代碼不同,因為這個圖形對象已經建立了,是以當渲染循環完成的時候,必須要丢棄它。不調用graphics.dispose()方法的話,将會導緻記憶體洩露以及程式崩潰。

應當總是確定調用dispose()來清理圖形對象。