程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> 關於JAVA >> 使用NetBeans進行J2ME開發(三):低級圖形用戶界面Canvas

使用NetBeans進行J2ME開發(三):低級圖形用戶界面Canvas

編輯:關於JAVA

在這一篇中,我將向大家介紹圖形用戶界面中的低級圖形用戶界面。所謂低級圖形用戶界面,指的是那種我們可以自己在上面畫圖的控件,它是和TextBox,List等等這些用戶控件剛好相對的概念,因為這些用戶控件的形狀是事先畫好的,無需我們程序員操心,所以稱為高級圖形界面。低級圖形用戶界面什麼東西都需要我們自己畫,所以比較復雜,當然也更加靈活,只有想不到,沒有畫不出,所以我們先介紹它。

在J2ME開發中,低級圖形用戶界面是由javax.microedition.lcdui.Canvas類實現的,我們只要繼承這個類,並實現這個類的paint方法,就可以隨心所欲的進行繪畫了。當然,繪畫之前,我們少不了要了解我們的手機屏幕究竟有多大的畫圖空間,這可以通過調用Canvas類的getWidth和getHeight方法實現。下面是一個簡短的程序,向大家演示了怎麼獲畫布的大小,同時,也算是一個小小的框架。首先,當然是創建我們自己的畫布,代碼如下: package com.xkland.j2me;

import javax.microedition.lcdui.Canvas;
import javax.microedition.lcdui.Graphics;
/** *//**
*
* @author 海邊沫沫
*/
public class MyCanvas extends Canvas {
   /** *//** Creates a new instance of MyCanvas */
   public MyCanvas() {
   }
   public void clearBackground(Graphics g){
     int color = g.getColor();
     g.setColor(0xffffff);
     g.fillRect(0,0,getWidth(),getHeight());
     g.setColor(color);
   }
   public void paint(Graphics g){
     //清除背景
     clearBackground(g);
     //顯示可供繪圖的區域的大小
     g.drawString("寬度:",10,10,Graphics.LEFT|Graphics.TOP);
     g.drawString(String.valueOf(getWidth()),50,10,Graphics.LEFT|Graphics.TOP);
     g.drawString("高度:",10,25,Graphics.LEFT|Graphics.TOP);
     g.drawString(String.valueOf(getHeight()),50,25,Graphics.LEFT|Graphics.TOP);
   }
}

第二個類當然就是我們的Midlet了,因為它是主程序嘛。在程序啟動的時候調用display.setCurrent將畫布設置為主界面,同時設置事件監聽器。代碼比較簡單,如下: packagecom.xkland.j2me;
import javax.microedition.midlet.*;
import javax.microedition.lcdui.*;
/** *//**
*
* @author 海邊沫沫
* @version
*/
public class CanvasTest extends MIDlet{
   private Canvas canvas = new MyCanvas();
   private Display display = null;
   private Command exitCommand = new Command("退出",Command.EXIT,1);
   public void startApp() {
     if(display==null){
       display = Display.getDisplay(this);
       canvas.addCommand(exitCommand);
       canvas.setCommandListener(new MyCommandListener(this,canvas));
       display.setCurrent(canvas);
     }
   }
   public void pauseApp() {
   }
   public void destroyApp(boolean unconditional) {
   }
}

第三個類當然是我們的事件監聽器類了,等一下我們會講到,Canvas支持許多低級事件,比如鍵盤的按鍵事件,所以我們這裡把事件監聽器單獨抽取出來,代碼如下: packagecom.xkland.j2me;
import javax.microedition.lcdui.CommandListener;
import javax.microedition.lcdui.Command;
import javax.microedition.lcdui.Displayable;
import javax.microedition.lcdui.Canvas;
/** *//**
*
* @author 海邊沫沫
*/
public class MyCommandListener implements CommandListener{
   private CanvasTest app;
   private Canvas canvas;
   /** *//** Creates a new instance of MyCommandListener */
   public MyCommandListener(CanvasTest app,Canvas canvas) {
     this.app = app;
     this.canvas = canvas;
   }
   public void commandAction(Command cmd, Displayable displayable){
     if(cmd.getLabel().equalsIgnoreCase("退出")){
       app.destroyApp(false);
       app.notifyDestroyed();
     }
   }
}

下面是運行效果:

知道了畫圖區域的大小,同時又知道Canvas可以支持許多低級事件,我們就可以發揮我們自己的想象力創建一個小游戲了。下面,我將寫一個簡單的拼圖游戲,只需要使用上下左右四個方向鍵操作即可,在事件監聽器中,我們只需響應Canvas的keyPressed()事件即可。代碼也不復雜,只需把上面的程序稍加擴展即可。當然,我們還需要准備一些圖片當素材。

首先,在網上隨便找一張圖片,使用圖形編輯軟件調整圖片的大小,然後再裁成3*4共12幅圖象。把這12幅圖象分別命名為1.png到12.png,同時還要准備一張全白的圖片,命名為0.png,這張圖片和前面的12張圖片一樣大小。在項目所在的文件夾下建立一個文件夾,取名為pictures,把這些圖片都拷貝進去。在NetBeans IDE左邊的文件選項卡中可以看到這些文件,如圖:

但是,在生成項目的時候,這些文件並不會自動打包到項目中,我們必須將這個文件夾捆綁為該項目的資源。在項目上點右鍵,在彈出的菜單中選擇屬性,彈出如下對話框,選中左邊的“庫和資源”,在右邊點擊“添加文件夾”按鈕即可:

下面是我的MyCanvas類的全部代碼,其它兩個類的代碼沒有改變。在這裡,我使用的圖片是174*280的大小,切割後的小圖片每一個都是58*70的大小,空白的圖片也是58*70的大小。請看代碼:

package com.xkland.j2me;
import javax.microedition.lcdui.Canvas;
import javax.microedition.lcdui.Graphics;
import javax.microedition.lcdui.Image;
import java.util.Random;
/** *//**
*
* @author 海邊沫沫
*/
public class MyCanvas extends Canvas {
   public int[][] pics = new int[4][4];
   public Image[] images = new Image[13];
   public int step = 0;
   public int spaceX = 3;
   public int spaceY = 0;
   public int spaceValue = 0;
   /** *//** Creates a new instance of MyCanvas */
   public MyCanvas() {
     //隨機填充數組
     for(int i=0;i<4;i++){
       for(int j=0;j<3;j++){
         pics[i][j] = i*3 + j + 1;
       }
     }
     pics[0][3] = 0;
     Random rand = new Random();
     for(int i=0; i<4; i++){
       int x1 = rand.nextInt(3);
       int y1 = rand.nextInt(4);
       int x2 = rand.nextInt(3);
       int y2 = rand.nextInt(4);
       int n = pics[y1][x1];
       pics[y1][x1] = pics[y2][x2];
       pics[y2][x2] = n;
     }
     //載入圖片
     for(int i=0; i<13; i++){
       try{
         images[i] = Image.createImage("/" + String.valueOf(i) + ".png");
       }catch(Exception e){
         //不做處理
       }
     }
   }
   public void clearBackground(Graphics g){
     int color = g.getColor();
     g.setColor(0xcccccc);
     g.fillRect(0,0,getWidth(),getHeight());
     g.setColor(color);
   }
   public void paint(Graphics g){
     //清除背景
     clearBackground(g);
     //繪制網格
     g.setColor(0x000000);
     g.drawRect(1,3,236,284);
     g.drawLine(1,74,237,74);
     g.drawLine(1,145,178,145);
     g.drawLine(1,216,178,216);
     g.drawLine(60,3,60,287);
     g.drawLine(119,3,119,287);
     g.drawLine(178,3,178,287);
     //根據pics數組和images數組的內容繪圖到網格中
     for(int i=0; i<4; i++){
       for(int j=0; j<3; j++){
         g.drawImage(images[pics[i][j]],j*59+2,i*71+4,Graphics.TOP|Graphics.LEFT);
       }
     }
     g.drawImage(images[pics[0][3]],179,4,Graphics.TOP|Graphics.LEFT);
     //繪制所用的步驟
     g.drawString("步數:",182,140,Graphics.TOP|Graphics.LEFT);
     g.setColor(0xffffff);
     g.fillRect(182,158,50,18);
     g.setColor(0xff0000);
     g.drawString(String.valueOf(step),187,160,Graphics.TOP|Graphics.LEFT);
   }
   public void keyPressed(int keyCode){
     switch(getGameAction(keyCode)){
       case RIGHT:
         right();
         break;
       case LEFT:
         left();
         break;
       case UP:
         up();
         break;
       case DOWN:
         down();
         break;
     }
    repaint();
   }
   public void up(){
     if(spaceY < 3){
       pics[spaceY][spaceX] = pics[spaceY+1][spaceX];
       pics[spaceY+1][spaceX] = 0;
       spaceY ++;
       step ++;
     }
   }
   public void down(){
     if(spaceY >0){
       pics[spaceY][spaceX] = pics[spaceY-1][spaceX];
       pics[spaceY-1][spaceX] = 0;
       spaceY --;
       step ++;
     }
   }
   public void left(){
     int rightLimit = 2;
     if(spaceY == 0){
       rightLimit = 3;
     }
     if(spaceX < rightLimit){
       pics[spaceY][spaceX] = pics[spaceY][spaceX+1];
       pics[spaceY][spaceX+1] = 0;
       spaceX ++;
       step ++;
     }
   }
   public void right(){
     if(spaceX > 0 ){
       pics[spaceY][spaceX] = pics[spaceY][spaceX -1];
       pics[spaceY][spaceX-1] = 0;
       spaceX --;
       step ++;
     }
   }
}

運行項目,得到如下的效果,使用上下左右四個鍵可以移動圖片:

游戲過程中的截圖:

游戲完成後的截圖:

當然,大家也可以自己添加拼圖完成後的判斷代碼,在拼圖成功後自動彈出提示信息。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved