J2ME遊戲開發技巧

來源:互聯網
上載者:User

//本文轉載自:http://www.itepub.net/pagecode/312350/2006/0428/4089.html

不久前我曾用J2ME開發了一個MotoT720下的彩色遊戲—寶石方塊(GridOne)。開發過程中積累了一些經驗,現在寫出來與大家分享。

使用雙緩衝避免螢幕閃爍

   雙緩衝技術是編寫J2ME遊戲程式的關鍵技術之一。實際上,雙緩衝技術是電腦動畫的一項傳統技術。造成螢幕閃爍的主要原因在於,畫面在顯示的同時,程式又在改變它,於是畫面閃爍。解決辦法就是在記憶體中開闢一片地區作為後台畫面,程式對它更新,修改,完成後再顯示它。這樣被顯示的映像永遠是已經完全畫好的映像,程式修改的將不是正在被顯示的映像。當然還有其它方法可以解決螢幕閃爍問題,但使用雙緩衝技術是一種值得推薦的解決方案。具體方法可參見如下代碼:

public class BlocksCanvas extends Canvas implements Runnable
{
Graphics bg;
Image buf;
public BlocksCanvas()
{
......
height = getHeight();
width = getWidth();
//按螢幕大小建立緩衝對象
buf = Image.createImage(width, height);
//將緩衝對象的Graphics附給bg
bg = buf.getGraphics();
......
}
public void run()
{......
for(i=0;i<ROWS;i++)
{
for(j=0;j<COLS;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= board[block_x][block_y];
bg.drawImage(imgs[c], x, y, Graphics.TOP | Graphics.LEFT);
}

public void paint(Graphics g)
{
g.drawImage(buf, 0, 0, Graphics.TOP | Graphics.LEFT);
}
}

   由上面代碼可見,雙緩衝思想體現在程式上就是要依次完成以下幾步工作:

   1. 定義一個Graphics對象bg和一個Image對象buf,按螢幕大小建立一個緩衝對象附給buf,然後取得buf的Graphics對象附給bg。在這裡,Graphics對象可以理解為緩衝的螢幕,Image對象則可當成緩衝螢幕上的圖片。

   2. 在bg(緩衝螢幕)上用drawImage()和drawString等語句畫圖,相當於在緩衝螢幕上畫圖。

   3. 調用repaint()語句,它的功能是告知系統調用paint()來完成真實螢幕的顯示。這裡需要注意的是,paint()是一個系統調用語句,不能手工調用,只能通過paint()語句來調用。

   4. 在paint(Graphics g)函數裡,將buf(緩衝螢幕上的圖片)畫到真實螢幕上。

   以上的步驟雖然看似繁瑣,但是效果還是很不錯的。如果想要在螢幕上顯示什麼東西,只管畫在bg上,然後調用repaint()將其顯示出來就可以了。

編寫自己的斷點函數

   圖1 斷點測試

   在開發J2ME程式過程中,最困擾人的問題就是程式容易莫名其妙地死機。當使用JBuilder或者CodeWarrior設定斷點功能來尋找程式錯誤時,死機的機率就更大了。即使不死機,也會擔心程式受到了意外的幹擾,所以一般不推薦使用開發工具內建的斷點功能。但有時候又需要一個功能來顯示當前各變數的值,以便查錯時做出正確的判斷。於是我想了一個辦法,就是編寫自己的斷點函數。具體代碼如下:

public class BlocksCanvas extends Canvas implements Runnable
{
private boolean stopFlag=false;//調試標誌
......
public void run()
{
//斷點位置1
testFun(“x:”+x+“y:”+y);
......
//斷點位置2
testFun(“”);
......
}
private void testFun(String str)
{
stopFlag=true;
//畫一個白色長方形
bg.setGrayScale(255);
bg.fillRect(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語句進入了死迴圈,程式停了下來。這時可以仔細地看清楚變數的值。然後當按下任意鍵時,keyPressed()函數捕捉到這一事件,將stopFlag設為false,死迴圈自動解開。使用此方法非常方便,只要在需要斷點的地方放置testFun()語句即可,一個程式可以放置多個testFun()語句,在迴圈語句中也可以放置testFun()語句。程式運行到testFun()語句會自動停下顯示變數值,按任意鍵程式又會自動運行,程式也不會受到意外的幹擾。圖1是調試時的。

   還有一點需要說明,此方法的testFun()語句必須放在run()函數中或者run()函數運行時調用的函數中,否則就會因為while()佔用了所有CPU時間而導致keyPressed()函數無法捕捉按鍵事件,最後導致死機。

   此方法只要稍加修改,就可以用做遊戲的暫停功能,而且比sleep()方法好,畢竟理論上sleep()方法不能無限期暫停下去。下面給出相應的代碼:

public class BlocksCanvas extends Canvas implements Runnable
{
private boolean stopFlag=false;//暫停標誌
......
public void run()
{......
testFun();
......
}

private void testFun()
{
while(stopFlag){}
}

public void keyPressed(int keyCode)
{
int action = getGameAction(keyCode);
if(action== FIRE)stopFlag=!stopFlag;
}
}

   該程式段的功能為,當使用者按下FIRE鍵時,遊戲暫停;再次按下FIRE鍵,遊戲繼續運行。
(未完待續)

 

 

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.