如何使用J2ME中的线程(1)

系统 1396 0

线程在 J2ME 开发中是不可或缺的一部分, J2ME 继承了 J2SE 中关于 java.lang 中的 Runnable 接口,以及 Thread 类。但是,由于 J2ME 应用的特殊性, J2ME<o:p></o:p>

程序中去除了部分 API ,没有线程组的概念,也没有 daemon 线程。 <o:p></o:p>

今天,我们从一个例子出发,来学习 J2ME 当中的线程的概念。我们选取的例子是俄罗斯方块。首先,有一些要注意的事项: <o:p></o:p>

1. 注意一点,要注意在 J2me 中不要使用浮点数,这样可以通过编译,但是不能通过预验证。因为一般手持设备都无法负担浮点运算的高负荷。 <o:p></o:p>

2. J2ME 程序当中,绝大多数的空间为图片所占有,我们可以看到,今天我们的例子没有任何图片,仅仅 5k ,如果是开发产品,不可避免的要使用图片, <o:p></o:p>

  但是尽量使用压缩率高的 png 图片,而且不要太过复杂,因为复杂的图片会使得图片变得很大。 <o:p></o:p>

3. 在程序中尽量使用常量特别是位置信息 , 这样当作修改的时候只要改一个量就可以了 , 而且当移植到其他平台的时候也会减少很多工作量 . 还有就是颜色 <o:p></o:p>

  信息等 . 不用每次记忆 , 重新构造 , 因为 J2me 中的颜色和 j2se 的不太一样 . 没有常量定义 .<o:p></o:p>

4. 游戏产品经常需要保护版权 , 而当今的很多反编译工具可以轻而易举地把 jar 文件的内容反编译过来 , 因此可以对程序进行模糊化处理 , 使得无法反编译 <o:p></o:p>

  或者反编译后无法理解 . 可以右键点击项目 , 在属性中选择 Build|Obfuscating, 选择模糊化级别 .<o:p></o:p>

5. 讲解中我们都使用 NetBeans 作为开发平台,有关安装事宜请访问 www.netbeans.org.<o:p></o:p>

  <o:p></o:p>

好,我们开始吧。 <o:p></o:p>

A. 首先,建立一个新的移动应用程序项目,取名 Tetris, 不要自动创建 Hello 程序,选取 MIDP1.0 CLDC1.0.<o:p></o:p>

B. 新建一个包,方法是右键点击项目,选取 New|Java Package, 取名 Tetris.<o:p></o:p>

C. 新建一个 Midlet ,同上,选取 New|Java Midlet, 取名 TetrisMidlet.<o:p></o:p>

D. 我们需要一个能够显示游戏的 Canvas, 因此新建一个 Class 名叫 TetrisCanvas, TetrisMidlet.java 中将 TetrisCanvas 作为当前可以显示的元素 :<o:p></o:p>

   现在的 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 ,并且实现 Canvas 的接口函数 paint(), 我们现在有了一个 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 类,然后生成它的实例,但是由于它已经 <o:p></o:p>

              继承了 Canvas 类,而 Java 中不允许多重继承,因此,我们在编程当中通常采取第二种做法,也就是让它实现 Runnable 接口,在成员中声明一个 Thread<o:p></o:p>

              成员,实例生成指向自己,然后实现 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. 程序逻辑:下面给出程序清单。程序中我们使用一个数组来存储方块的信息 , 一共有十九种 , 还有一个数组来存储当前的画面方格的内容 . 在程序中 <o:p></o:p>

   有一个 paint 方法来实现重画 , 注意绘制的先后次序 , 当程序规模变得很大的时候 , 重画的效率就非常重要 , 需要进行优化 . 我们在程序中使用了背景 ,<o:p></o:p>

   在没有背景的情况下 , 程序仅 5k, 采用背景后 , 程序 47k, 可见对图片的优化至关重要 .<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 中只存储颜色信息 <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 矩阵,内容为带边框的主绘图区。 <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>

如何使用J2ME中的线程(1)


更多文章、技术交流、商务合作、联系博主

微信扫码或搜索:z360901061

微信扫一扫加我为好友

QQ号联系: 360901061

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描下面二维码支持博主2元、5元、10元、20元等您想捐的金额吧,狠狠点击下面给点支持吧,站长非常感激您!手机微信长按不能支付解决办法:请将微信支付二维码保存到相册,切换到微信,然后点击微信右上角扫一扫功能,选择支付二维码完成支付。

【本文对您有帮助就好】

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描上面二维码支持博主2元、5元、10元、自定义金额等您想捐的金额吧,站长会非常 感谢您的哦!!!

发表我的评论
最新评论 总共0条评论