程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> JAVA編程入門知識 >> 經典收藏:J2ME Game的開發筆記

經典收藏:J2ME Game的開發筆記

編輯:JAVA編程入門知識
  J2ME Game開發筆記-嘗試IO優化
  正在開發的一個游戲,由於讀地圖的時候做了圖片切割,所以速度比較慢。(在我開發上一個游戲的時候,讀取地圖時沒有裝載切割圖片,速度非常快,看來IO操作的速度和createImage,drawImage相比是微不足道的)對於IO的優化也許根本不會明顯的提高速度,但我還是試了一下。
  
  分析了一下代碼,在最初的代碼中為了比較方便的讀取各種類型的數據,使用DataInputStream套接InputStream。可是我仔細看了一下我讀取得數據,居然都是byte,唯一的一個char也是被我用兩個byte手工組裝起來的。這下,DataInputStream看來是不需要了。於是我做了個實驗,沒改動之前讀取地圖耗時1242ms,將DataInputStream去掉直接使用InputStream耗時1065ms,雖然每次試驗的結果都稍有不同,但大概還是節約了200ms左右。
  
  還能再加快點嗎?再觀察一下代碼,我發現數據是通過多次的read操作讀取進來的。太過頻繁的io操作會不會降低速度呢?假如用一個字節數組作緩沖一次性將數據都讀進來會不會快點?嗯,試一試才知道。但是我怎麼知道一個流的大小呢?InputStream的avaliable方法總是返回-1啊!打開兩次流,第一次先計算大小?對了,還有一個方法。直接將文件大小寫到文件前面。地圖文件是用自己的編輯器生成的,知道大小很輕易。於是我在文件前面用兩個byte紀錄了文件的大小,先從流中讀取2個byte,得到文件大小後,再用read(byte[],int,int)方法將整個流讀取到緩沖中。然後,我的所有數據操作都從緩沖中讀取。好,試驗一下,結果是:1154ms。阿? 慢了近100ms。事實證實了這個猜想是錯誤的。原因?也許只有了解KVM的機制才知道。
  
  弄完速度的問題,我又覺得讀取文件的try塊太大了,因為是邊讀邊處理數據,所以try塊變得很大。try塊太大會增加class文件的大小。於是我用一個方法將讀取byte的操作封裝起來,當然這個方法是聲明為private static的,但究竟能不能內聯,只有編譯器和kvm才知道。在這個方法內部從流中讀取一個字節的時候采用了try,catch結構,這就使一個大try塊分散成若干小try塊。試驗了一下,耗時1089ms,诶,還是慢了點。現在對於速度的要求比空間更高,更何況減小try塊節省的10幾個字節打包後基本忽略不計了。所以這個優化又失敗了。
  
  小結:能使用簡單流的時候就不要使用復雜流,不要太相信理論上的說法,只有試了才知道。
  
  注:試驗數據是Nokia3100手機的實機測試數據,在Nokia 3300上這個數據更小些,最快約800多ms
  
  壓縮還是不壓縮
  做J2ME的都知道Midlet Suite的容量實在太小了,於是不免想做點壓縮。前些天,我就嘗試了一次壓縮。我自己定義的地圖文件裡有3層數據,其中2,3層有大片連續分布的相同的值。 唉?我一琢磨,使用一個簡單的行長編碼壓縮,僅對這個值進行行長編碼,算法很簡單速度又不慢,卻可以大大減小地圖文件的大小。看起來真的很不錯诶!說干就干,忙了半天,又改地圖編輯器,又改游戲中讀地圖的代碼。總算搞定,試了一下,原來2.23k的一個文件被壓縮到900多字節。似乎很不錯啊,接著我打了個jar包,卻忽然發現這個jar文件似乎並沒有比原來小阿!似乎還大了點。我連忙找出備份的代碼,果然原來的jar更小點!怎麼回事啊??我忽然想到,jar本身就是壓縮格式的。難道。。。我趕緊用WinRAR打開兩次的jar文件觀察。~~~~~原來如此!原來的jar中,2.23k的文件的包大小為185字節,而我現在的jar中,900多字節的文件的包大小為216字節。也就是說,我自己先壓縮一遍的文件打包後還不如不壓縮的小!
  
  看來自己做壓縮之前,一定要先看看你想壓縮的文件在包裡面的大小。還有對於png文件,使用某些工具優化後,在包裡面的大小卻變大了。這個還真是要注重阿~!
  
  移植一法
  近日觀察某些游戲的源代碼(反編譯後的),發現有個方法挺方便游戲的移植的。定義一個接口(比如stringTable)將游戲中所用到的靜態字符串都定義為接口的常量。然後,讓使用到這些字符串的類實現stringTable接口。這樣移植的時候只要修改接口裡面的字符串就行了。當然,對於游戲中坐標的定位,最好使用getWidth(),getHeight()還有Font類的方法stringWidth,不要定死了。這樣的話,移植工作就比較輕松了。
  
  鍵盤響應
  不同的機型對於鍵盤事件的響應不一樣。經過我的測試,Nokia 7210,3100一次只能接受一個按鍵信息。(我寫了個測試程序,發現假如一個鍵被按下後沒有松開,則KeyPressed事件不會再產生,即其他鍵的按下操作無效)所以,用緩沖處理控制精靈運動時,假如規定只能四方向運動。假如up已按下,再按下left,精靈的運動方向並不會改變。不過將按鍵緩沖。按下up,按下left不釋放,松開up---精靈就會向左運動。(在松開up後產生了left的KeyPressed事件!希奇嗎?松開up後我並沒有進行"按下"left這個動作--left鍵在up松開前就被按下了且沒有松開。似乎機器一直在監測鍵盤上各鍵的狀態,並且有一個等待隊列。)
  
  在wtk的標准模擬器上就不同了。它可以接受多個按鍵“同時”按下的事件。所以假如用四個並列的if處理,精靈是可以斜著運動的。假如用if else處理,則假如已經按下一個方向鍵,然後再按下另一個,是否能改變方向受到if else 語句中順序的影響。即,假如是 if(up) else if(left),則會先檢查up鍵,所以假如已經按下了left,再按up是可以向上運動的,反過來就不行了。(這個自然:)
  
  其它的機型由於手頭沒有機器,我也沒試過。應該也是如此吧。
  
  多機型移植經驗談
  開發的時候平台是Nokia 40,然後移植到Nokia 60, Moto V, SE等,總結一下大概需要幾個版本。
  1 Nokia 40版, 使用Midp1.0+Nokia UI API
  2 Nokia 60版, 使用Midp1.0+NOkia UI API
  3 Nokia Midp2.0版,如6600,7610,使用Midp2.0
  4 Moto V版,使用Midp2.0
  5 SE版,使用Midp2.0
  6 三星s100,s200,c100,使用Midp2.0
  
  幾點開發經驗:
  1 各機型之間最大的差別就是屏幕大小不同。所以游戲中要能自適應屏幕大小
  2 不使用Midp2.0的GameAPI會比較方便移植,只要自己封裝切圖,旋轉等函數即可。NokiaUI API和Midp2。0都支持圖片選轉。2.0支持的更好。注重Nokia 60不支持創建可變的透明圖片,所以要用其他方法代替。
  3 NOkia 6600,7610的UI API有問題(圖片旋轉),所以用了Midp2.0代替
  4 支持MIDP2。0的機器程序大致相同,其中MOto,SE,SX都差不多。但也有細微差別。如SE不支持全屏。所以screenSizeChanged方法無效。
  5 說說聲音播放。NOkia s40上我果斷不用聲音,一是容量限制,二是太難聽。其他機型都可以支持midi和wav.不過沒有發現可以同時播放2個midi的機型,moto v和se都可以同時播放midi和wav,nokia則不行。
 
  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved