J2ME開發手機游戲寶石方塊_第1頁
J2ME開發手機游戲寶石方塊_第2頁
J2ME開發手機游戲寶石方塊_第3頁
J2ME開發手機游戲寶石方塊_第4頁
J2ME開發手機游戲寶石方塊_第5頁
已閱讀5頁,還剩6頁未讀 繼續免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領

文檔簡介

1、J2ME開發手機游戲:寶石方塊 2004-03-24 21:24:29 不久前我曾用J2ME開發了一個MotoT720下的彩色游戲:寶石方塊(GridOne)。開發過程中積累了一些經驗,現在寫出來與大家分享。 使用雙緩沖避免屏幕閃爍 雙緩沖技術是編寫J2ME游戲程序的關鍵技術之一。實際上,雙緩沖技術是計算機動畫的一項傳統技術。造成屏幕閃爍的主要原因在于,畫面在顯示的同時,程序又在改變它,于是畫面閃爍。解決辦法就是在內存中開辟一片區域作為后臺畫面,程序對它更新,修改,完成后再顯示它。這樣被顯示的圖像永遠是已經完全畫好的圖像,程序修改的將不是正在被顯示的圖像。當然還有其它方法可以解決屏幕閃爍問題,

2、但使用雙緩沖技術是一種值得推薦的解決方案。具體方法可參見如下代碼: public class BlocksCanvas extends Canvas implements RunnableGraphics bg;Image buf;public BlocksCanvas().height = getHeight();width = getWidth();/按屏幕大小建立緩沖對象buf = Image.createImage(width, height);/將緩沖對象的Graphics附給bgbg = buf.getGraphics();. public void run().for(i=0;i

3、 for(j=0;j /畫方塊drawBlock(x,y);repaint();private void drawBlock(int block_x, int block_y) /取得方塊的坐標int x = getLeft(block_x);int y = getTop(block_y);/取得方塊的顏色int c= boardblock_xblock_y; bg.drawImage(imgsc, x, y, Graphics.TOP | Graphics.LEFT);public void paint(Graphics g)g.drawImage(buf, 0, 0, Graphics.T

4、OP | Graphics.LEFT); 由上面代碼可見,雙緩沖思想體現在程序上就是要依次完成以下幾步工作: 1 定義一個Graphics對象bg和一個Image對象buf,按屏幕大小建立一個緩沖對象附給buf,然后取得buf的Graphics對象附給bg。在這里,Graphics對象可以理解為緩沖的屏幕,Image對象則可當成緩沖屏幕上的圖片。 2 在bg(緩沖屏幕)上用drawImage()和drawString等語句畫圖,相當于在緩沖屏幕上畫圖。 3 調用repaint()語句,它的功能是告知系統調用paint()來完成真實屏幕的顯示。這里需要注意的是,paint()是一個系統調用語句,

5、不能手工調用,只能通過paint()語句來調用。 4 在paint(Graphics g)函數里,將buf(緩沖屏幕上的圖片)畫到真實屏幕上。 以上的步驟雖然看似繁瑣,但是效果還是很不錯的。如果想要在屏幕上顯示什么東西,只管畫在bg上,然后調用repaint()將其顯示出來就可以了。編寫自己的斷點函數 圖1 斷點測試 在開發J2ME程序過程中,最困擾人的問題就是程序容易莫名其妙地死機。當使用JBuilder或者CodeWarrior設置斷點功能來查找程序錯誤時,死機的概率就更大了。即使不死機,也會擔心程序受到了意外的干擾,所以一般不推薦使用開發工具自帶的斷點功能。但有時候又需要一個功能來顯示當

6、前各變量的值,以便查錯時做出正確的判斷。于是我想了一個辦法,就是編寫自己的斷點函數。具體代碼如下: public class BlocksCanvas extends Canvas implements Runnableprivate boolean stopFlag=false;/調試標志.public void run()/斷點位置1testFun(“x:”+x+“y:”+y);./斷點位置2testFun(“”);.private void testFun(String str) stopFlag=true;/畫一個白色長方形bg.setGrayScale(255);bg.fillRec

7、t(0,0, fontW, fontH);/在白色長方形上顯示str的內容bg.setGrayScale(0);bg.drawString(str, 0,0, Graphics.TOP | Graphics.LEFT);repaint();while(stopFlag)public void keyPressed(int keyCode) stopFlag=false; 首先定義一個boolean類型的stopFlag變量來記錄調試標志。一開始它的值為false,進入testFun()函數后,值設為true。顯示完str的內容后,因為stopFlag的值為true,所以while語句進入了死循

8、環,程序停了下來。這時可以仔細地看清楚變量的值。然后當按下任意鍵時,keyPressed()函數捕捉到這一事件,將stopFlag設為false,死循環自動解開。使用此方法非常方便,只要在需要斷點的地方放置testFun()語句即可,一個程序可以放置多個testFun()語句,在循環語句中也可以放置testFun()語句。程序運行到testFun()語句會自動停下顯示變量值,按任意鍵程序又會自動運行,程序也不會受到意外的干擾。圖1是調試時的截圖。 還有一點需要說明,此方法的testFun()語句必須放在run()函數中或者run()函數運行時調用的函數中,否則就會因為while()占用了所有C

9、PU時間而導致keyPressed()函數無法捕捉按鍵事件,最后導致死機。 此方法只要稍加修改,就可以用做游戲的暫停功能,而且比sleep()方法好,畢竟理論上sleep()方法不能無限期暫停下去。下面給出相應的代碼: public class BlocksCanvas extends Canvas implements Runnableprivate boolean stopFlag=false;/暫停標志.public void run().testFun();.private void testFun() while(stopFlag)public void keyPressed(int

10、 keyCode) int action = getGameAction(keyCode);if(action= FIRE)stopFlag=!stopFlag; 該程序段的功能為,當使用者按下FIRE鍵時,游戲暫停;再次按下FIRE鍵,游戲繼續運行。 編寫自己的工具類 因為手機內存和功能的限制,J2ME只提供了部分的J2SE工具類供使用者調用。所以有時我們不得不編寫自己的工具類來實現一些特殊的功能。下面給出的kSet類就類似于J2SE中Set工具類的功能。它用來記錄游戲中被刪去的方塊集合,同時保證集合中沒有相同元素。 /*Description: Set類在J2ME上的實現*Date:200

11、3.2.28*Author:TomJava*email:tomjava*/public class kSet/用單鏈表實現private kSetNode head;public kSet()head=null;/將kSet清空public void clear()head=null;/向kSet中添加元素 public boolean add(int x,int y)kSetNode node=new kSetNode(x,y);return add(node);/向kSet中添加元素public boolean add(kSetNode node) if(!contains(node) n

12、ode.next=head;head=node;return true;elsereturn false;/判斷kSet是否為空public boolean isEmpty()if(head=null)return true;elsereturn false;/摘下鏈表頭元素并返回此元素public kSetNode getFirst() kSetNode p=head;head=p.next;return p;/遍歷kSet,如果有相同元素返回true,否則返回false public boolean contains(kSetNode node)kSetNode p = head;whil

13、e (p != null) if(p.equals(node)return true;p=p.next; return false; /kSet中的元素public class kSetNode public int x,y;public kSetNode next;public kSetNode(int x,int y)this.x=x;this.y=y;next=null;public boolean equals(kSetNode node)if(node.x=x&&node.y=y)return true;elsereturn false;public int getX

14、()return x;public int getY()return y; kSetNode類負責記錄被刪除方塊的坐標,它重載equals()方法用來判斷兩個方塊是否是同一個方塊。kSet類是由kSetNode對象組成的沒有相同元素的集合,用單鏈表實現,并且提供了 getFirst()、add()、clear()、isEmpty()、contains()等方法供其它類調用。編寫和使用一些這樣的工具類,將大大加快編程的速度,也使程序變得更加清晰。 矯正屏幕坐標 GridOne這個游戲是專門為MotoT720開發的,也就是說游戲背景圖片大小和MotoT720型手機的大小是相等的。如果它在那些屏幕比

15、MotoT720大的手機上運行,游戲背景圖片會顯示在屏幕左上角而影響美觀,這時就要用到屏幕矯正技術,使得游戲背景圖片居中顯示。矯正屏幕坐標代碼如下: public class BlocksCanvas extends Canvas implements Runnableprivate final int addX;/坐標矯正private final int addY;private final int SCREEN_X;/屏幕頂點private final int SCREEN_Y;private final int WAITBLOCK_X;/等待方塊頂點private final int

16、WAITBLOCK_Y;private final int SCORES_X;/分數頂點private final int SCORES_Y;private final int STAR_X;/五角星的頂點private final int STAR_Y;public BlocksCanvas()/取得當前手機屏幕的高度和寬度height = getHeight();width = getWidth();/坐標矯正量 addX = (width-120)/2; addY = (height-142)/2;/初始化屏幕參數SCREEN_X = addX + 48;/屏幕頂點SCREEN_Y =

17、addY + 10;WAITBLOCK_X = addX + 19;/等待方塊頂點WAITBLOCK_Y = addY + 103;SCORES_X = addX + 36;/分數頂點SCORES_Y = addY + 34;STAR_X=addX+4;/五角星的頂點STAR_Y=addY+70; 首先把所有有關屏幕的參數都定義成private final int型變量。這里之所以加上final 修飾符,是因為不希望變量附初值后,它們的值會發生變化;之所以不加static修飾符,是因為要在其函數中初始化變量,而不是在定義時就初始化好了。先用getHeight()和getWidth()函數取得當

18、前手機屏幕的高度和寬度,再計算出需要的偏移量addX和addY,然后加到各屏幕參數上,這樣游戲內容就會居中顯示了。圖2與圖3是效果比較圖。 圖2 矯正前 圖3 矯正后 還有一點需要注意,用getHeight()取得的并不是手機屏幕的真實高度,而是手機屏幕的高度減去Command標簽高度,因為屏幕需要留出地方顯示Command標簽。 合理使用內存 本來使用Java編程是不需要關心內存使用的,因為Java有它引以為豪的垃圾處理機制。但到了J2ME里,情況發生了變化,因為手機的內存只有屈指可數的幾百K,再也不能像在J2SE里那樣大手大腳了。否則就會發現,即使程序沒有任何語法和邏輯錯誤,也不能在模擬器

19、中運行。下面給出合理使用內存的幾個建議: 1 盡可能使用本地變量代替類成員,減少對象的創建,最好能重新利用對象; 2 不要試圖在初始化的時候把所有Form或者Canvas對象都讀入內存中,而應該在需要的時候再創建,雖然這樣在顯示上會有一些延遲,但是總比程序不能運行或者內存溢出要好; 3 一旦對象不需要使用就及時將其置為null,以便能夠被垃圾處理器回收,適當的時候調用System.gc()語句提示虛擬機調用垃圾處理器; 4.必須記住Java的內存管理是有向邊機制,所以對于不使用的對象,千萬不要讓正在使用的對象指向它,以免內存得不到回收; 5.盡量使圖片占有的字節數小一點,可以使用Firewor

20、ks在保證圖片質量同時減小圖片的大小; 即使做到上面幾點,也不能保證程序不會發生內存泄漏,因為手機內存畢竟那么少。所以我提出最后一個建議,就是先完成游戲的主體部分,使它能夠正常運行并沒有內存泄漏,再慢慢擴展游戲,給它加上封面和其它功能。一旦發現內存不足,再去掉部分功能。使游戲更有魅力 編寫游戲當然希望它能吸引人,我覺得下面幾個地方值得大家注意: 1 注意控制游戲的節奏 原來我在削除方塊的時候,什么都不做就直接刪除,然后開始一個新的循環,讓等待的方塊往下掉。在實際運行的時候感覺效果不是很好,因為削得越快,上面的方塊也掉得越快,讓游戲者有一種措手不及的感覺。后來我在刪除方塊的時候,用空循環停頓了幾秒鐘,這樣就給了游戲者一個反應時間,感覺就好些了,而且如果連削的話,反應時間會

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯系上傳者。文件的所有權益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經權益所有人同意不得將文件中的內容挪作商業或盈利用途。
  • 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
  • 6. 下載文件中如有侵權或不適當內容,請與我們聯系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論