京山游侠

专注技术,拒绝扯淡
posts - 50, comments - 868, trackbacks - 0, articles - 0
  BlogJava :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理
  在这一篇中,我将向大家介绍图形用户界面中的低级图形用户界面。所谓低级图形用户界面,指的是那种我们可以自己在上面画图的控件,它是和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将画布设置为主界面,同时设置事件监听器。代码比较简单,如下:
package com.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支持许多低级事件,比如键盘的按键事件,所以我们这里把事件监听器单独抽取出来,代码如下:
package com.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();
        }

    }

    
}

  下面是运行效果:
25.PNG


  知道了画图区域的大小,同时又知道Canvas可以支持许多低级事件,我们就可以发挥我们自己的想象力创建一个小游戏了。下面,我将写一个简单的拼图游戏,只需要使用上下左右四个方向键操作即可,在事件监听器中,我们只需响应Canvas的keyPressed()事件即可。代码也不复杂,只需把上面的程序稍加扩展即可。当然,我们还需要准备一些图片当素材。

  首先,在网上随便找一张图片,使用图形编辑软件调整图片的大小,然后再裁成3*4共12幅图象。把这12幅图象分别命名为1.png到12.png,同时还要准备一张全白的图片,命名为0.png,这张图片和前面的12张图片一样大小。在项目所在的文件夹下建立一个文件夹,取名为pictures,把这些图片都拷贝进去。在NetBeans IDE左边的文件选项卡中可以看到这些文件,如图:
26.PNG


  但是,在生成项目的时候,这些文件并不会自动打包到项目中,我们必须将这个文件夹捆绑为该项目的资源。在项目上点右键,在弹出的菜单中选择属性,弹出如下对话框,选中左边的“库和资源”,在右边点击“添加文件夹”按钮即可:

27.PNG

  下面是我的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 
++;
        }

        
    }
    
}


  运行项目,得到如下的效果,使用上下左右四个键可以移动图片:

29.PNG

  游戏过程中的截图:

30.PNG

  游戏完成后的截图:

28.PNG

  当然,大家也可以自己添加拼图完成后的判断代码,在拼图成功后自动弹出提示信息。

评论

# re: 使用NetBeans进行J2ME开发(三):低级图形用户界面Canvas  回复  更多评论   

2007-08-04 23:38 by prcvictim
对我很有帮助.太感谢了

# re: 使用NetBeans进行J2ME开发(三):低级图形用户界面Canvas  回复  更多评论   

2007-08-05 08:49 by BeanSoft
感谢分享!

# re: 使用NetBeans进行J2ME开发(三):低级图形用户界面Canvas  回复  更多评论   

2007-08-06 00:31 by dreamstone
找时间试试,记得上次使用netBean都是1年多前的事情了,不知道新的版本变化大不

# re: 使用NetBeans进行J2ME开发(三):低级图形用户界面Canvas[未登录]  回复  更多评论   

2007-08-23 15:24 by 影子
rand.nextInt(3);
这个方法没有啊 老是报错啊

# re: 使用NetBeans进行J2ME开发(三):低级图形用户界面Canvas  回复  更多评论   

2007-08-26 17:45 by 海边沫沫
@影子

import java.util.Random;

Random rand = new Random();

# re: 使用NetBeans进行J2ME开发(三):低级图形用户界面Canvas[未登录]  回复  更多评论   

2007-08-27 14:53 by 影子
谢谢了 我再试试

# re: 使用NetBeans进行J2ME开发(三):低级图形用户界面Canvas[未登录]  回复  更多评论   

2008-01-02 08:10 by 游子
请问pakage那里找?还有import 文件??
能上传上来吗?

# re: 使用NetBeans进行J2ME开发(三):低级图形用户界面Canvas[未登录]  回复  更多评论   

2008-07-02 22:35 by yang
你这边用的是哪个切割软件啊

# re: 使用NetBeans进行J2ME开发(三):低级图形用户界面Canvas  回复  更多评论   

2009-02-24 16:20 by 不错
java.lang.NullPointerException:
at com.xkland.j2me.MyCanvas.paint(MyCanvas.java:83)
怎么经常报这个错误

# re: 使用NetBeans进行J2ME开发(三):低级图形用户界面Canvas  回复  更多评论   

2009-04-08 19:23 by little
没有报错,正常运行,但是没有图片显示啊,请问是什么原因啊

# re: 使用NetBeans进行J2ME开发(三):低级图形用户界面Canvas  回复  更多评论   

2009-04-10 17:45 by little
for(int i=0; i<13; i++){
try{
images[i] = Image.createImage("/" + String.valueOf(i) + ".png");
}catch(Exception e){
//不做处理
}
}
这一段有问题,想请教一下,createImage(“地址”),这个参数地址和实际地址怎么对应啊。。。。

只有注册用户登录后才能发表评论。


网站导航: