程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> 關於JAVA >> Java游戲開發中應始終堅持的10項基本原則

Java游戲開發中應始終堅持的10項基本原則

編輯:關於JAVA

關於文章中涉及的兩個杜撰概念:

一、繪圖器:眾所周知,Java GUI以paint進行繪圖,以repaint進行圖像刷新,而完成repaint及paint這一連貫過程中所用到繪圖組件,我將其稱為繪圖器。就我個人的體會,繪圖器的調用時機應始終處於repaint之後paint之前,即通過repaint觸發刷新後執行,當其中的具體邏輯完成其對應的圖像繪制後,再通過統一接口將其圖像插入paint中,為了匹配需要,繪圖器應始終以接口方式實現。

二、監聽器:這裡所說的監聽器,並不是特指某個Listener組件,而是包括Java游戲中所需的所有監聽器集合。由於Java游戲中很可能會切換不同的游戲模式,而不同模式游戲中需要處理的鼠標或鍵盤事件也不盡相同。所以在Java游戲開發(游戲開發培訓 )中,我們需要一個可替換的監聽器集合,用以變更不同游戲模式下的不同監聽事件,為了匹配需要,監聽器應始終以接口方式實現。

正文,關於Java游戲開發中應始終堅持的10項基本原則:

1、始終保持畫布的唯一性。

現實生活中,人類通過口腔及消化道攝取的營養物質可以被心、肝、脾、肺、腎等內髒吸收,卻沒有人會想給自己的心、肝、脾、肺、腎上也弄個嘴,因為一致性的功能實現只要有一個就足夠了。但是,有時我們不經意的在游戲中add、remove不同panel或canvas以求轉換畫面的行為,無異於是想給游戲的心、肝、脾、肺、腎上裝嘴的不智之舉,切忌Java的GUI都是畫出來的,重繪就好,沒有切換組件的必要,否則費力不討好。

2、始終以接口方式轉換監聽及處理圖像繪制,務必將視圖及邏輯層分開。

針對一些混合類型的游戲,比如SLG+AVG、RPG+STG,我們將面臨不同模式下游戲的監聽器及繪圖器切換問題。

這時最簡單的抉擇莫過於為每一個游戲類型都訂制一個對應的面板進行切換,這樣雖表面上方省心,但卻也是最費力而不討好的,且不說閃爍問題需要單獨解決,資源占用問題,光冗余代碼就夠人頭痛了。

其次就是在一個面板中針對不同游戲類型使用switch判斷以切換監聽及繪圖,事件數量少時固然可以,效率也不錯,但稍微多一點恐怕就不那麼簡單,更多時則僅余郁悶,同樣不建議使用。

就我個人所見,解決這一問題的最好方法莫過於沿用MVC模式,以接口方式構建繪圖器及監聽器,當游戲出現變更時,我們僅僅需要切換監聽及繪圖接口,就可以迅速轉變游戲內容,而無需區別對待不同的實現,這樣即避免了組件切換的閃爍及延遲,也精簡了代碼,更有利於開發時的模塊劃分。

3、始終以靜態方式加載游戲常用資源,緩存常用對象,並及時釋放無用資源。

即使歷史發展到今天,Java依舊沒有徹底擺脫其系統資源殺手的可憎面目,GC機制也導致我們無法適時地釋放資源,new的越多,系統也變得越慢,這對於大量使用圖形資源的游戲來講尤其要命。所以我們要盡一切可能令常用資源靜態化為唯一實例以避免反復調用,而將一些調用後不會再使用或很少使用的資源迅速 null以等待GC自動回收。否則,你將發現你的游戲距離內存溢出是那樣的近……

4、始終以循環方式展開游戲,利用線程控制游戲流程,避免出現僵直現象。

事實上所謂的游戲開發,在某種程度上不過是由程序員制作出的一種夾雜著各類圖形算法,用以適時地展示各種資源的幻燈程序;唯一的區別在於,普通幻燈程序中人機交互性較弱,而游戲的人機交互性較強罷了。

我們都知道,幻燈程序在展示中無論如何跳轉展示頁,也必然有其固定的begin與end頁面,而且也勢必能重復從頭至尾順序循環其begin與end,以此構成一個幻燈片。

實際上游戲制作也一樣,無論游戲流程如何轉變,游戲都會有也必然會有一個主流程,或者說一個主循環體,這樣我們才能由游戲開始進行到游戲結束,而不是從一個結束到另一個結束,也就是說無論游戲中細節分支有多少,它的主流程處理及判定也必然是順序的。針對這一特性,決定了我們應將游戲主體代碼至於一個大的循環體之內,再利用線程控制循環體中的游戲進度,從而更好的順應這一流程。簡單的說,我們應將循環體中每一個使用到的繪圖器都當作於Flash中的一桢,而線程的各種控制當作時間軸,用以調節不同桢的播放速度及調用時機,以此完成各種不同的事件交互。

5、始終在處理復雜繪圖時直接准備貼圖而非由程序繪制。

我們都知道Java繪圖事實上是GDI實現,因此其繪制復雜畫面的效率也就可想而知。通常強況下,除非當前的效果非編程不能實現,或者其所造成的資源損耗確實微小到可以忽略不計,否則最好的方法就是用空間換效率,准備好圖片直接貼上去吧,寧可增加些程序體積,也不要讓玩家因等待的憤怒而問候你祖宗八輩。

6、始終保證repaint僅刷新需要部分,避免無謂的全局重繪。

每repaint一次,事實上就是將paint中的圖形打印到窗體上一次,窗體越大,處理的圖像越復雜,repaint所造成的資源損耗也勢必越多,運行效率也勢必越低。但反過來說,由於Java允許我們限定repaint的范圍,因而我們可以將刷新限定在某一特定區域內,更准確地說我們可以僅在需要變更畫面的位置上才進行刷新,以此將損耗降低到最低限度,總體上說,即使我們會因為計算刷新區域額外花費些許時間,總體上講也比全局repaint要快得多。

7、始終雙緩沖游戲圖像避免閃爍現象發生。

對於Java繪圖而言,每次調用repaint方法時都會清除整個屏幕,然後paint才顯示畫面。而萬一系統速度不夠,在清除背景和繪制圖像間的短暫間隔內被用戶看見,就出現了所謂的閃爍現象;簡單來講閃爍的成因就是運算效率不足,使得repaint與paint不連貫造成的。

針對這種情況,我們需要利用雙緩沖技術加以解決。

雙緩沖實現其實簡單至極,主要過程就是先創建一個等大小於希望繪制圖形的Image,而後取得其Graphics,每當paint繪圖時我們不直接將圖像繪制於paint函數的Graphics上,而是繪制於我們創建的緩沖圖像的Graphics上,當繪制完成後再調用paint函數提供的 drawImage方法,將整個後台圖像一次畫到屏幕上去。這種方法的優點在於大部分繪制是在後台進行的。將後台繪制的圖像一次繪制到屏幕上。

這時只要系統速度正常,我們所看到的繪圖將不再有閃爍現象發生。

8、始終在自繪組件的桌面游戲中應用AWT或SWT而非Swing。

眾所周知,Swing(JFC)的GUI是以AWT為基礎在本地窗體繪制而成,相較AWT雖然提供了更為豐富的組件,但也意味著它占用了更多的資源。而事實上,大多數Java桌面游戲組件是由開發者所針對性繪制,並非Swing庫提供,也不需要Swing庫支持,我們完全可以放棄Swing而選擇AWT或 SWT(SWT繪圖與AWT/Swing繪圖在方法上略有區別,但本質一樣)這種直接Native而來的界面,實在不需勞動Swing他老人家,平白的耗費掉那些本就因使用Java應用而稀缺的系統資源。

9、始終別忘了在Graphics處理完畢後dispose。

Graphics的dispose與數據庫Connection的close可謂異曲同工。為此我特意做了一個實驗,在死循環中無間隔無優化的反復 repaint一幅2000X2000的大圖,應用dispose時雖然刷新很慢並伴隨閃爍但總體講正常,而去掉dispose運行大約一分鐘後萬惡的溢出大神降臨……

當然,就像Connection應在全部操作完成後才close一樣,Graphics也僅在全部繪圖完畢後才需要dispose,也就是當最後一個paint最後一次draw後,別忘了留個dispose關門,除非你很想看見溢出大神……

10、始終以運算效率為第一優先,可適當放棄代碼可讀性,可適當違背OO原則。

以Java進行游戲開發,最大的問題莫過於系統資源的損耗,在關鍵問題上,就別死抱著OO不放了。

若你能始終堅持以上十點,雖然別指望就此超越C/C++游戲的運行效率,但已能與Delphi游戲爭鋒而無愧色,傲視於vb6、Flash、rmxp、rmvx等工具開發的游戲而鄙夷之。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved