程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> J2ME >> 如何使用J2ME中的線程

如何使用J2ME中的線程

編輯:J2ME
線程在J2ME開發中是不可或缺的一部分,J2ME繼承了J2SE中關於Java.lang中的Runnable接口,以及Thread類。但是,由於J2ME應用的特殊性,J2ME 程序中去除了部分API,沒有線程組的概念,也沒有daemon線程。 今天,我們從一個例子出發,來學習J2ME當中的線程的概念。我們選取的例子是俄羅斯方塊。首先,有一些要注意的事項: 1.注意一點,要注意在J2ME中不要使用浮點數,這樣可以通過編譯,但是不能通過預驗證。因為一般手持設備都無法負擔浮點運算的高負荷。 2.在J2ME程序當中,絕大多數的空間為圖片所占有,我們可以看到,今天我們的例子沒有任何圖片,僅僅5k,如果是開發產品,不可避免的要使用圖片, 但是盡量使用壓縮率高的png圖片,而且不要太過復雜,因為復雜的圖片會使得圖片變得很大。 3.在程序中盡量使用常量特別是位置信息,這樣當作修改的時候只要改一個量就可以了,而且當移植到其他平台的時候也會減少很多工作量.還有就是顏色   信息等.不用每次記憶,重新構造,因為J2ME中的顏色和J2SE的不太一樣.沒有常量定義. 4.游戲產品經常需要保護版權,而當今的很多反編譯工具可以輕而易舉地把jar文件的內容反編譯過來,因此可以對程序進行模糊化處理,使得無法反編譯   或者反編譯後無法理解.可以右鍵點擊項目,在屬性中選擇Build|Obfuscating,選擇模糊化級別. 5.講解中我們都使用NetBeans作為開發平台,有關安裝事宜請訪問www.Netbeans.org.   好,我們開始吧。 A. 首先,建立一個新的移動應用程序項目,取名Tetris, 不要自動創建Hello程序,選取MIDP1.0和CLDC1.0. B. 新建一個包,方法是右鍵點擊項目,選取New|Java Package,取名Tetris. C. 新建一個Midlet,同上,選取New|Java Midlet, 取名TetrisMidlet. D. 我們需要一個能夠顯示游戲的Canvas, 因此新建一個Class名叫TetrisCanvas, 在TetrisMidlet.Java中將TetrisCanvas作為當前可以顯示的元素:    現在的TetrisMidlet.Java如下:               package Tetris;                             import Javax.microedition.midlet.*;               import Javax.microedition.lcdui.*;                             /**                *                * @author  lin                * @version                */               public class TetrisMidlet extends MIDlet {                   public void startApp() {                       Display display = Display.getDisplay( this );                       // TetrisCanvas extends Canvas which extends Displayable so it can                       // be displayed directly                       display.setCurrent( new TetrisCanvas());                   }                                     public void pauseApp() {                   }                                     public void destroyApp(boolean unconditional) {                   }               }                             由於TetrisCanvas繼承了Canvas,所以可以被TetrisMidlet所顯示. E.  這裡,我們需要將TetrisCanvas繼承Canvas,並且實現Canvas的接口函數paint(),我們現在有了一個TetrisCanvas的框架了。               package Tetris;                             import Javax.microedition.lcdui.*;               public class TetrisCanvas extends Canvas {                   /** Creates a new instance of TetrisCanvas */                   public TetrisCanvas() {                                 }                                 protected void paint(Graphics g){                                     }               }                             下面我們需要使得TetrisCanvas具有Thread的特性,這裡有兩種方法,一種是讓TetrisCanvas繼承Thread類,然後生成它的實例,但是由於它已經               繼承了Canvas類,而Java中不允許多重繼承,因此,我們在編程當中通常采取第二種做法,也就是讓它實現Runnable接口,在成員中聲明一個Thread               成員,實例生成指向自己,然後實現run方法。                             也就是這樣:               public class TetrisCanvas extends Canvas implements Runnable {                      private Thread Blocker = null;                      ...                      public TetrisCanvas(){                          Blocker = new Thread(this);                Blocker.start();            }                                     ...                      public void run(){                                    while (Blocker != null) {                                                                       }                                           }                      ...                 } F. 程序邏輯:下面給出程序清單。程序中我們使用一個數組來存儲方塊的信息,一共有十九種,還有一個數組來存儲當前的畫面方格的內容.在程序中    有一個paint方法來實現重畫,注意繪制的先後次序,當程序規模變得很大的時候,重畫的效率就非常重要,需要進行優化.我們在程序中使用了背景,    在沒有背景的情況下,程序僅5k,采用背景後,程序47k,可見對圖片的優化至關重要.                 /*                * TetrisCanvas.Java                *                * Created on 2005年7月13日, 上午11:31                *                * To change this template, choose Tools | Options and locate the template under                * the Source Creation and Management node. Right-click the template and choose                * Open. You can then make changes to the template in the Source Editor.                */                             package Tetris;                             import Java.util.*;               import Java.lang.Math;               import Javax.microedition.lcdui.*;                                           /**                *                * @author lin                */               public class TetrisCanvas extends Canvas implements Runnable{                   private Thread Blocker = null;                   private Random generator;                   private int FutureBlockType, BlockType,LastType,LastX,LastY,BlockX,BlockY ;                   private int BlockLines,BlockScore;                   private int BlockSpeed,CurSpeed;                                     private static final int COLOR_GRAY      = 0x00eeeeee;                   private static final int COLOR_RED       = 0x00ff0000;                   private static final int COLOR_BLACK     = 0x00000000;                   private static final int COLOR_WHITE     = 0x00ffffff;                   private static final int COLOR_BLUE      = 0x000000ff;                   private static final int COLOR_LIGHT_BLUE= 0x0089a5d1;                   private static final int COLOR_DARK_GRAY = 0x00808080;                   private static final int COLOR_BACKGROUND= COLOR_LIGHT_BLUE;                                     private static final int BLOCK_SIZE = 7;                   private static final int CANVAS_SIZE_WIDTH = 12;                   private static final int CANVAS_SIZE_HEIGHT = 22;                   private static final int CANVAS_OFFSET_X = 5;                   private static final int CANVAS_OFFSET_Y = 7;                                 /**                    * The paint status.                    */                   boolean ISCLEAR = false;                   boolean ISDOWN = false;                   boolean ISDEL = false;                                     /**                    * the block information matrix.                    */                   int BlockInfo[][]={{1,0,1,1,1,2,1,3,0xff0000,2},                                    {0,1,1,1,2,1,3,1,0xff0000,4},                                    {0,0,0,1,1,1,1,2,0x0000ff,2},                                    {0,1,1,0,1,1,2,0,0x0000ff,3},                                    {0,1,0,2,1,0,1,1,0x00ff00,2},                                    {0,0,1,0,1,1,2,1,0x00ff00,3},                                            {0,0,0,1,1,0,1,1,0xffff00,2},                                    {0,1,1,0,1,1,1,2,0x00ffff,2},                                    {0,1,1,0,1,1,2,1,0x00ffff,3},                                    {1,0,1,1,1,2,2,1,0x00ffff,3},                                    {0,1,1,1,1,2,2,1,0x00ffff,3},                                    {0,1,0,2,1,1,2,1,0xff00ff,3},                                    {0,0,1,0,1,1,1,2,0xff00ff,3},                                    {0,1,1,1,2,0,2,1,0xff00ff,3},                                    {1,0,1,1,1,2,2,2,0xff00ff,3},                                    {0,0,0,1,1,1,2,1,0xffffff,3},                                    {1,0,1,1,1,2,2,0,0xffffff,3},                                    {0,1,1,1,2,1,2,2,0xffffff,3},                                    {0,2,1,0,1,1,1,2,0xffffff,3},                                    };                   // Gridmatrix 中只存儲顏色信息                   int Gridmatrix[][]=new int[CANVAS_SIZE_HEIGHT][CANVAS_SIZE_WIDTH];                                 /**                    * Initialize the applet. Resize and load images.                    */                   public void init() {                                           BlockType=Math.abs(generator.nextInt()%19);                                           FutureBlockType=Math.abs(generator.nextInt()%19);                                           LastType=BlockType;                                                                                      BlockLines=0;                                           BlockScore=0;                                           BlockSpeed=1;                                           CurSpeed=BlockSpeed;                       BlockX=4;     LastX=BlockX;                                           BlockY=0;     LastY=BlockY;                                             //初始化Gridmatrix矩陣,內容為帶邊框的主繪圖區。                                           for(int i=0;i<CANVAS_SIZE_HEIGHT;i++)                                               for(int j=0;j<CANVAS_SIZE_WIDTH;j++)                                               Gridmatrix[i][j]=0;                                           for(int i=0;i<CANVAS_SIZE_WIDTH;i++)                           Gridmatrix[CANVAS_SIZE_HEIGHT-1][i]=COLOR_DARK_GRAY;                                           for(int i=0;i<CANVAS_SIZE_HEIGHT;i++) {                                              Gridmatrix[i][0]=COLOR_DARK_GRAY;                                              Gridmatrix[i][11]=COLOR_DARK_GRAY;                                           }                    }                                     /** Creates a new instance of TetrisCanvas */                   public TetrisCanvas() {                       generator = new Random( System.currentTimeMillis() );                       init();                       Blocker = new Thread(this);                       Blocker.start();                   }                                 private void draw3DBlock(Graphics g, int c, int x, int y, int width, int height){                       int color = g.getColor();                       g.setColor( COLOR_WHITE );                       g.drawRect( x, y, width, height );                       g.setColor(c);                       g.fillRect( x + 1, y + 1, width-2, height-2 );                       g.setColor( COLOR_BLACK );                       g.drawLine( x + width-1, y, x + width-1, y + height-1 );                       g.drawLine( x, y + height-1, x + width-1, y + height-1 );                       g.setColor(color);                   }                                     public static boolean drawText(Graphics g, String str, int x, int y, int anchor, int color, int size) {                       Font f_old,f_new;                       int c_old;                       try {                           f_old = g.getFont();                           f_new =  Font.getFont(Font.FACE_SYSTEM,Font.STYLE_BOLD,size);                           g.setFont(f_new);                           c_old = g.getColor();                           g.setColor(color);                                                     g.drawString(str, x, y, anchor );                                                     g.setColor(c_old);                           g.setFont(f_old);                                                     return true;                             }catch (Exception ex) {                           return false;                       }                   }                                        protected void paint(Graphics g){                       //畫背景                       try{                           Image image_Splash = Image.createImage("/back.png");                           g.drawImage(image_Splash, 0, 0,Graphics.TOP | Graphics.LEFT);                       }                       catch(Exception ex) {                       }                                             //畫下一個要出現的方塊                       drawText(g, "下一個", 91, 5, Graphics.TOP| Graphics.LEFT, COLOR_BLUE, Font.SIZE_SMALL);                       g.setColor(COLOR_GRAY);                       g.drawRoundRect(91, 18, 26, 30, 2, 2);                       g.setColor(COLOR_DARK_GRAY);                       g.fillRoundRect(92, 19, 24, 28, 2, 2);                                           for(int i=0;i<=3;i++)                                               draw3DBlock(g, BlockInfo[FutureBlockType][8],                                      93+BlockInfo[FutureBlockType][i*2+1]*BLOCK_SIZE,                                      20+BlockInfo[FutureBlockType][i*2]*BLOCK_SIZE,                                      BLOCK_SIZE,BLOCK_SIZE);                                              drawText(g, "速度:"+String.valueOf(CurSpeed), 91, 60, Graphics.TOP| Graphics.LEFT, COLOR_BLUE, Font.SIZE_SMALL);                       drawText(g, "行數:"+String.valueOf(BlockLines), 91, 75, Graphics.TOP| Graphics.LEFT, COLOR_BLUE, Font.SIZE_SMALL);                       drawText(g, "成績:", 91, 90, Graphics.TOP| Graphics.LEFT, COLOR_BLUE, Font.SIZE_SMALL);                       g.setColor(COLOR_GRAY);                       g.drawRoundRect(91, 105, 26, 20, 2, 2);                       g.setColor(COLOR_DARK_GRAY);                       g.fillRoundRect(92, 106, 24, 18, 2, 2);                           drawText(g, String.valueOf(BlockScore), 93, 107, Graphics.TOP| Graphics.LEFT, COLOR_WHITE, Font.SIZE_MEDIUM);                                             //畫當前戰況                                           for(int i=0;i<CANVAS_SIZE_HEIGHT-1;i++)                           for(int j=1;j<CANVAS_SIZE_WIDTH-1;j++)                               if (Gridmatrix[i][j]!=0)                                       draw3DBlock(g,Gridmatrix[i][j],CANVAS_OFFSET_X+j*BLOCK_SIZE,                                               CANVAS_OFFSET_Y+i*BLOCK_SIZE,                                               BLOCK_SIZE,BLOCK_SIZE);                                                                 if (!ISDOWN){                                           //畫上新的方塊                                                LastX=BlockX; LastY=BlockY; LastType=BlockType;                                                for(int i=0;i<=3;i++)                                                       draw3DBlock(g,BlockInfo[BlockType][8],                                                              CANVAS_OFFSET_X+BlockX*BLOCK_SIZE+BlockInfo[BlockType][i*2+1]*BLOCK_SIZE,                                                              CANVAS_OFFSET_Y+BlockY*BLOCK_SIZE+BlockInfo[BlockType][i*2]*BLOCK_SIZE,                                                              BLOCK_SIZE,BLOCK_SIZE);                                           }                   }                                 private boolean feasible(){                                    for(int i=0;i<=3;i++)                                if (Gridmatrix[BlockY+BlockInfo[BlockType][i*2]][BlockX+BlockInfo[BlockType][i*2+1]]!=0)                                       return false;                                    return true;                   }                                     private void delline(){                                    for(int i=0;i<=3;i++)                                         Gridmatrix[BlockY+BlockInfo[BlockType][i*2]][BlockX+BlockInfo[BlockType][i*2+1]]=BlockInfo[BlockType][8];                                    int temp=4;                                    boolean CanSkip=false;                                     int i=CANVAS_SIZE_HEIGHT-2;                                    while((temp>0)&&(i>=1)){                                             CanSkip=false;                                         label1: for(int j=1;j<=CANVAS_SIZE_WIDTH-2;j++){                                             if (Gridmatrix[i][j]==0)  {CanSkip=true; i--; break label1;}                                         }                                         if (!CanSkip){                                             temp--;                                              for(int k=i;k>=1;k--)                                              for(int l=1;l<=CANVAS_SIZE_WIDTH-2;l++)                                                   Gridmatrix[k][l]=Gridmatrix[k-1][l];                                             BlockLines++;                                             BlockScore+=200;                                             if((BlockScore%2000)<200) CurSpeed++;                                              }                                    }                   }                                     public void run() {                     while (Blocker != null) {                                            if(!ISDOWN){                                                BlockY++;                                                if (!feasible()) {                                                     ISDOWN=true; BlockY--; delline();                                                     try {Thread.sleep(400);} catch (InterruptedException e){}                                                }                                                else{                                                                  repaint();                                                                  try {Thread.sleep(950-100*(int)BlockSpeed);} catch (InterruptedException e){}                                                     }                                                  }                                                  else{   BlockScore+=50;                                                                if((BlockScore%2000)<50) CurSpeed++;                                                                   ISDOWN=false;                                                                repaint();                                                                BlockSpeed=CurSpeed;                                                                BlockType=FutureBlockType;                                                                FutureBlockType=Math.abs(generator.nextInt()%19);                                                                   BlockX=4;     LastX=BlockX;                                                                BlockY=0;     LastY=BlockY;                                                                if (!feasible()) { init();}                                                  }                          }                          Blocker = null;                   }                                 protected void keyPressed(int keyCode) {                       //處理按下鍵盤的事件,這是Canvas的實例方法                       switch (getGameAction(keyCode)) {//將按鍵的值轉化成方向常量                           case Canvas.UP://向上                                             break;                           case Canvas.DOWN://向下                               BlockY++;                               if (!feasible()) BlockY--;                                   repaint();                               BlockSpeed=9;                               //Blocker.run();                               break;                           case Canvas.LEFT://向左                                                                       BlockX--;                                                                       if (!feasible()) BlockX++;                                                                       break;                           case Canvas.RIGHT://向右                                                                       BlockX++;                                                                       if (!feasible()) BlockX--;                               break;                           case Canvas.FIRE:                                                                       int tempBlockType=BlockType;                                                                       if (BlockType==1) BlockType=-1;                                   else if (BlockType==3) BlockType=1;                                   else if (BlockType==5) BlockType=3;                                   else if (BlockType==6) BlockType=5;                                   else if (BlockType==10) BlockType=6;                                   else if (BlockType==14) BlockType=10;                                   else if (BlockType==18) BlockType=14;                                                                       BlockType++;                                                                       if (!feasible()) BlockType=tempBlockType;                               break;                           default:                               break;                       }                       repaint(); return;                   }                 }  
  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved