線程在 J2ME 開發(fā)中是不可或缺的一部分, J2ME 繼承了 J2SE 中關(guān)于 java.lang 中的 Runnable 接口,以及 Thread 類。但是,由于 J2ME 應(yīng)用的特殊性, J2ME<o:p></o:p>
程序中去除了部分 API ,沒有線程組的概念,也沒有 daemon 線程。 <o:p></o:p>
今天,我們從一個(gè)例子出發(fā),來學(xué)習(xí) J2ME 當(dāng)中的線程的概念。我們選取的例子是俄羅斯方塊。首先,有一些要注意的事項(xiàng): <o:p></o:p>
1. 注意一點(diǎn),要注意在 J2me 中不要使用浮點(diǎn)數(shù),這樣可以通過編譯,但是不能通過預(yù)驗(yàn)證。因?yàn)橐话闶殖衷O(shè)備都無法負(fù)擔(dān)浮點(diǎn)運(yùn)算的高負(fù)荷。 <o:p></o:p>
2. 在 J2ME 程序當(dāng)中,絕大多數(shù)的空間為圖片所占有,我們可以看到,今天我們的例子沒有任何圖片,僅僅 5k ,如果是開發(fā)產(chǎn)品,不可避免的要使用圖片, <o:p></o:p>
? 但是盡量使用壓縮率高的 png 圖片,而且不要太過復(fù)雜,因?yàn)閺?fù)雜的圖片會(huì)使得圖片變得很大。 <o:p></o:p>
3. 在程序中盡量使用常量特別是位置信息 , 這樣當(dāng)作修改的時(shí)候只要改一個(gè)量就可以了 , 而且當(dāng)移植到其他平臺(tái)的時(shí)候也會(huì)減少很多工作量 . 還有就是顏色 <o:p></o:p>
? 信息等 . 不用每次記憶 , 重新構(gòu)造 , 因?yàn)? J2me 中的顏色和 j2se 的不太一樣 . 沒有常量定義 .<o:p></o:p>
4. 游戲產(chǎn)品經(jīng)常需要保護(hù)版權(quán) , 而當(dāng)今的很多反編譯工具可以輕而易舉地把 jar 文件的內(nèi)容反編譯過來 , 因此可以對(duì)程序進(jìn)行模糊化處理 , 使得無法反編譯 <o:p></o:p>
? 或者反編譯后無法理解 . 可以右鍵點(diǎn)擊項(xiàng)目 , 在屬性中選擇 Build|Obfuscating, 選擇模糊化級(jí)別 .<o:p></o:p>
5. 講解中我們都使用 NetBeans 作為開發(fā)平臺(tái),有關(guān)安裝事宜請(qǐng)?jiān)L問 www.netbeans.org.<o:p></o:p>
? <o:p></o:p>
好,我們開始吧。 <o:p></o:p>
A. 首先,建立一個(gè)新的移動(dòng)應(yīng)用程序項(xiàng)目,取名 Tetris, 不要自動(dòng)創(chuàng)建 Hello 程序,選取 MIDP1.0 和 CLDC1.0.<o:p></o:p>
B. 新建一個(gè)包,方法是右鍵點(diǎn)擊項(xiàng)目,選取 New|Java Package, 取名 Tetris.<o:p></o:p>
C. 新建一個(gè) Midlet ,同上,選取 New|Java Midlet, 取名 TetrisMidlet.<o:p></o:p>
D. 我們需要一個(gè)能夠顯示游戲的 Canvas, 因此新建一個(gè) Class 名叫 TetrisCanvas, 在 TetrisMidlet.java 中將 TetrisCanvas 作為當(dāng)前可以顯示的元素 :<o:p></o:p>
?? 現(xiàn)在的 TetrisMidlet.java 如下 :<o:p></o:p>
????????????? package Tetris;<o:p></o:p>
????????????? <o:p></o:p>
????????????? import javax.microedition.midlet.*;<o:p></o:p>
????????????? import javax.microedition.lcdui.*;<o:p></o:p>
????????????? <o:p></o:p>
????????????? /**<o:p></o:p>
????????????? ? *<o:p></o:p>
????????????? ? * @author ? lin<o:p></o:p>
????????????? ? * @version<o:p></o:p>
????????????? ? */<o:p></o:p>
????????????? public class TetrisMidlet extends MIDlet {<o:p></o:p>
????????????? ??? public void startApp() {<o:p></o:p>
????????????? ??????? Display display = Display.getDisplay( this );<o:p></o:p>
????????????? ??????? // TetrisCanvas extends Canvas which extends Displayable so it can<o:p></o:p>
????????????? ??????? // be displayed directly<o:p></o:p>
????????????? ??????? display.setCurrent( new TetrisCanvas());<o:p></o:p>
????????????? ??? }<o:p></o:p>
????????????? ??? <o:p></o:p>
????????????? ??? public void pauseApp() {<o:p></o:p>
????????????? ??? }<o:p></o:p>
????????????? ??? <o:p></o:p>
????????????? ??? public void destroyApp(boolean unconditional) {<o:p></o:p>
????????????? ??? }<o:p></o:p>
????????????? }<o:p></o:p>
????????????? <o:p></o:p>
????????????? 由于 TetrisCanvas 繼承了 Canvas, 所以可以被 TetrisMidlet 所顯示 .<o:p></o:p>
E. ? 這里,我們需要將 TetrisCanvas 繼承 Canvas ,并且實(shí)現(xiàn) Canvas 的接口函數(shù) paint(), 我們現(xiàn)在有了一個(gè) TetrisCanvas 的框架了。 <o:p></o:p>
????????????? package Tetris;<o:p></o:p>
????????????? <o:p></o:p>
????????????? import javax.microedition.lcdui.*;<o:p></o:p>
????????????? public class TetrisCanvas extends Canvas {<o:p></o:p>
????????????? ??? /** Creates a new instance of TetrisCanvas */<o:p></o:p>
????????????? ??? public TetrisCanvas() {<o:p></o:p>
????????????? <o:p></o:p>
????????????? ??? }<o:p></o:p>
????????????? <o:p></o:p>
????????????? ??? protected void paint(Graphics g){<o:p></o:p>
????????????? ??? <o:p></o:p>
????????????? ??? }<o:p></o:p>
????????????? }<o:p></o:p>
????????????? <o:p></o:p>
????????????? 下面我們需要使得 TetrisCanvas 具有 Thread 的特性,這里有兩種方法,一種是讓 TetrisCanvas 繼承 Thread 類,然后生成它的實(shí)例,但是由于它已經(jīng) <o:p></o:p>
????????????? 繼承了 Canvas 類,而 Java 中不允許多重繼承,因此,我們?cè)诰幊坍?dāng)中通常采取第二種做法,也就是讓它實(shí)現(xiàn) Runnable 接口,在成員中聲明一個(gè) Thread<o:p></o:p>
????????????? 成員,實(shí)例生成指向自己,然后實(shí)現(xiàn) run 方法。 <o:p></o:p>
????????????? <o:p></o:p>
?????? ?????? 也就是這樣: <o:p></o:p>
????????????? public class TetrisCanvas extends Canvas implements Runnable {<o:p></o:p>
???????????????????? private Thread Blocker = null;<o:p></o:p>
???????????????????? ...<o:p></o:p>
???????????????????? public TetrisCanvas(){<o:p></o:p>
???????????????????? ??? Blocker = new Thread(this);<o:p></o:p>
?????? ??????? Blocker.start();<o:p></o:p>
?????? ??? }<o:p></o:p>
?????? ??????? <o:p></o:p>
???????????????????? ...<o:p></o:p>
???????????????????? public void run(){<o:p></o:p>
?????????????????????????????????? while (Blocker != null) {<o:p></o:p>
?????????????????????????????????? <o:p></o:p>
?????????????????????????????????? }<o:p></o:p>
???????????????????? <o:p></o:p>
???????????????????? }<o:p></o:p>
???????????????????? ...<o:p></o:p>
<o:p>?</o:p>
????????????? }<o:p></o:p>
F. 程序邏輯:下面給出程序清單。程序中我們使用一個(gè)數(shù)組來存儲(chǔ)方塊的信息 , 一共有十九種 , 還有一個(gè)數(shù)組來存儲(chǔ)當(dāng)前的畫面方格的內(nèi)容 . 在程序中 <o:p></o:p>
?? 有一個(gè) paint 方法來實(shí)現(xiàn)重畫 , 注意繪制的先后次序 , 當(dāng)程序規(guī)模變得很大的時(shí)候 , 重畫的效率就非常重要 , 需要進(jìn)行優(yōu)化 . 我們?cè)诔绦蛑惺褂昧吮尘? ,<o:p></o:p>
?? 在沒有背景的情況下 , 程序僅 5k, 采用背景后 , 程序 47k, 可見對(duì)圖片的優(yōu)化至關(guān)重要 .<o:p></o:p>
<o:p>?</o:p>
????????????? /*<o:p></o:p>
????????????? ? * TetrisCanvas.java<o:p></o:p>
????????????? ? *<o:p></o:p>
????????????? ? * Created on 2005 年 7 月 13 日 , 上午 11:31<o:p></o:p>
????????????? ? *<o:p></o:p>
????????????? ? * To change this template, choose Tools | Options and locate the template under<o:p></o:p>
????????????? ? * the Source Creation and Management node. Right-click the template and choose<o:p></o:p>
????????????? ? * Open. You can then make changes to the template in the Source Editor.<o:p></o:p>
????????????? ? */<o:p></o:p>
????????????? <o:p></o:p>
????????????? package Tetris;<o:p></o:p>
????????????? <o:p></o:p>
????????????? import java.util.*;<o:p></o:p>
????????????? import java.lang.Math;<o:p></o:p>
????????????? import javax.microedition.lcdui.*;<o:p></o:p>
????????????? <o:p></o:p>
????????????? <o:p></o:p>
????????????? /**<o:p></o:p>
????????????? ? *<o:p></o:p>
????????????? ? * @author lin<o:p></o:p>
????????????? ? */<o:p></o:p>
????????????? public class TetrisCanvas extends Canvas implements Runnable{<o:p></o:p>
????????????? ??? private Thread Blocker = null;<o:p></o:p>
????????????? ??? private Random generator;<o:p></o:p>
????????????? ??? private int FutureBlockType, BlockType,LastType,LastX,LastY,BlockX,BlockY ;<o:p></o:p>
????????????? ??? private int BlockLines,BlockScore;<o:p></o:p>
????????????? ??? private int BlockSpeed,CurSpeed;<o:p></o:p>
????????????? ??? <o:p></o:p>
????????????? ??? private static final int COLOR_GRAY ????? = 0x00eeeeee;<o:p></o:p>
????????????? ??? private static final int COLOR_RED ?????? = 0x00ff0000;<o:p></o:p>
????????????? ??? private static final int COLOR_BLACK ???? = 0x00000000;<o:p></o:p>
????????????? ??? private static final int COLOR_WHITE ???? = 0x00ffffff;<o:p></o:p>
????????????? ??? private static final int COLOR_BLUE ????? = 0x000000ff;<o:p></o:p>
????????????? ??? private static final int COLOR_LIGHT_BLUE= 0x0089a5d1;<o:p></o:p>
????????????? ??? private static final int COLOR_DARK_GRAY = 0x00808080;<o:p></o:p>
????????????? ??? private static final int COLOR_BACKGROUND= COLOR_LIGHT_BLUE;<o:p></o:p>
????????????? ??? <o:p></o:p>
????????????? ??? private static final int BLOCK_SIZE = 7;<o:p></o:p>
????????????? ??? private static final int CANVAS_SIZE_WIDTH = 12;<o:p></o:p>
????????????? ??? private static final int CANVAS_SIZE_HEIGHT = 22;<o:p></o:p>
????????????? ??? private static final int CANVAS_OFFSET_X = 5;<o:p></o:p>
????????????? ??? private static final int CANVAS_OFFSET_Y = 7;<o:p></o:p>
????????????? <o:p></o:p>
????????????? ??? /**<o:p></o:p>
????????????? ???? * The paint status.<o:p></o:p>
????????????? ???? */<o:p></o:p>
????????????? ??? boolean ISCLEAR = false;<o:p></o:p>
????????????? ??? boolean ISDOWN = false;<o:p></o:p>
????????????? ??? boolean ISDEL = false;<o:p></o:p>
????????????? ??? <o:p></o:p>
????????????? ??? /**<o:p></o:p>
????????????? ???? * the block information matrix.<o:p></o:p>
????????????? ???? */<o:p></o:p>
????????????? ??? int BlockInfo[][]={{1,0,1,1,1,2,1,3,0xff0000,2},<o:p></o:p>
??????????????????????????? ?????? {0,1,1,1,2,1,3,1,0xff0000,4},<o:p></o:p>
??????????????????????????? ?????? {0,0,0,1,1,1,1,2,0x0000ff,2},<o:p></o:p>
??????????????????????????? ?????? {0,1,1,0,1,1,2,0,0x0000ff,3},<o:p></o:p>
??????????????????????????? ?????? {0,1,0,2,1,0,1,1,0x00ff00,2},<o:p></o:p>
??????????????????????????? ?????? {0,0,1,0,1,1,2,1,0x00ff00,3}, ???????? <o:p></o:p>
??????????????????????????? ?????? {0,0,0,1,1,0,1,1,0xffff00,2},<o:p></o:p>
??????????????????????????? ?????? {0,1,1,0,1,1,1,2,0x00ffff,2},<o:p></o:p>
??????????????????????????? ?????? {0,1,1,0,1,1,2,1,0x00ffff,3},<o:p></o:p>
??????????????????????????? ?????? {1,0,1,1,1,2,2,1,0x00ffff,3},<o:p></o:p>
??????????????????????????? ?????? {0,1,1,1,1,2,2,1,0x00ffff,3},<o:p></o:p>
??????????????????????????? ?????? {0,1,0,2,1,1,2,1,0xff00ff,3},<o:p></o:p>
??????????????????????????? ?????? {0,0,1,0,1,1,1,2,0xff00ff,3},<o:p></o:p>
??????????????????????????? ?????? {0,1,1,1,2,0,2,1,0xff00ff,3},<o:p></o:p>
??????????????????????????? ?????? {1,0,1,1,1,2,2,2,0xff00ff,3},<o:p></o:p>
??????????????????????????? ?????? {0,0,0,1,1,1,2,1,0xffffff,3},<o:p></o:p>
??????????????????????????? ?????? {1,0,1,1,1,2,2,0,0xffffff,3},<o:p></o:p>
??????????????????????????? ?????? {0,1,1,1,2,1,2,2,0xffffff,3},<o:p></o:p>
??????????????????????????? ?????? {0,2,1,0,1,1,1,2,0xffffff,3},<o:p></o:p>
??????????????????????????? ?????? };<o:p></o:p>
????????????? ??? // Gridmatrix 中只存儲(chǔ)顏色信息 <o:p></o:p>
????????????? ??? int Gridmatrix[][]=new int[CANVAS_SIZE_HEIGHT][CANVAS_SIZE_WIDTH];<o:p></o:p>
????????????? <o:p></o:p>
????????????? ??? /**<o:p></o:p>
????????????? ???? * Initialize the applet. Resize and load images.<o:p></o:p>
????????????? ???? */<o:p></o:p>
????????????? ??? public void init() {<o:p></o:p>
????????????????????????????????????????? BlockType=Math.abs(generator.nextInt()%19);<o:p></o:p>
????????????????????????????????????????? FutureBlockType=Math.abs(generator.nextInt()%19);<o:p></o:p>
????????????????????????????????????????? LastType=BlockType;<o:p></o:p>
?????????????????????????????????? ??????? <o:p></o:p>
????????????????????????????????????????? BlockLines=0;<o:p></o:p>
????????????????????????????????????????? BlockScore=0;<o:p></o:p>
????????????????????????????????????????? BlockSpeed=1;<o:p></o:p>
????????????????????????????????????????? CurSpeed=BlockSpeed;<o:p></o:p>
????????????? ??????? BlockX=4; ??? ? LastX=BlockX;<o:p></o:p>
????????????????????????????????????????? BlockY=0; ???? LastY=BlockY;<o:p></o:p>
????????????? ??????? <o:p></o:p>
????????????? ??????? // 初始化 Gridmatrix 矩陣,內(nèi)容為帶邊框的主繪圖區(qū)。 <o:p></o:p>
????????????????????????????????????????? for(int i=0;i<CANVAS_SIZE_HEIGHT;i++)<o:p></o:p>
????????????????????????????????????????? ??? for(int j=0;j<CANVAS_SIZE_WIDTH;j++)<o:p></o:p>
????????????????????????????????????????? ??? Gridmatrix[i][j]=0;<o:p></o:p>
????????????????????????????????????????? for(int i=0;i<CANVAS_SIZE_WIDTH;i++) <o:p></o:p>
????????????? ??????????? Gridmatrix[CANVAS_SIZE_HEIGHT-1][i]=COLOR_DARK_GRAY;<o:p></o:p>
????????????????????????????????????????? for(int i=0;i<CANVAS_SIZE_HEIGHT;i++) {<o:p></o:p>
??????????????????????????? ???? ??????????? Gridmatrix[i][0]=COLOR_DARK_GRAY;<o:p></o:p>
??????????????????????????? ???? ??????????? Gridmatrix[i][11]=COLOR_DARK_GRAY;<o:p></o:p>
????????????????????????????????????????? } ? <o:p></o:p>
????????????? ??? }<o:p></o:p>
????????????? ??? <o:p></o:p>
????????????? ??? /** Creates a new instance of TetrisCanvas */<o:p></o:p>
????????????? ??? public TetrisCanvas() {<o:p></o:p>
????????????? ??????? generator = new Random( System.currentTimeMillis() );<o:p></o:p>
????????????? ??????? init();<o:p></o:p>
????????????? ??????? Blocker = new Thread(this);<o:p></o:p>
????????????? ??????? Blocker.start();<o:p></o:p>
????????????? ??? }<o:p></o:p>
????????????? <o:p></o:p>
更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號(hào)聯(lián)系: 360901061
您的支持是博主寫作最大的動(dòng)力,如果您喜歡我的文章,感覺我的文章對(duì)您有幫助,請(qǐng)用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點(diǎn)擊下面給點(diǎn)支持吧,站長(zhǎng)非常感激您!手機(jī)微信長(zhǎng)按不能支付解決辦法:請(qǐng)將微信支付二維碼保存到相冊(cè),切換到微信,然后點(diǎn)擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對(duì)您有幫助就好】元
