用户操作
[即时聊天] [发私信] [加为好友]
bluesnow 张ID:xuejinyoulan
107807次访问,排名827(-1)好友188人,关注者324
萍扶仙影卧冰床,雪浸肌莹傲百芳。
春早婀娜纤骨瘦,岁寒旖旎玉容香。
幽兰嫩蕊三分逊,碧柳纤枝几度茫。
QQ:61925615
msn:xuejinyoulan@hotmail.com
xuejinyoulan的文章
原创 13 篇
翻译 6 篇
转载 78 篇
评论 221 篇
最近评论
bobo_wwb:你们不知道么?FireFox已经针对Chrome推出新版本了。
cl61917380:我在看央视版的
一开始不是有说是死于过度疲劳吧!
cl61917380:我只能说IE不好用!
tquanong:那书我看过,呵呵,当时不是25岁嘛?哈呵
zhang62369138:我也刚看了李小龙传奇
文章分类
收藏
    相册
    存档
    软件项目交易
    订阅我的博客
    XML聚合  FeedSky
    订阅到鲜果
    订阅到Google
    订阅到抓虾
    订阅到BlogLines
    订阅到Yahoo
    订阅到GouGou
    订阅到飞鸽
    订阅到Rojo
    订阅到newsgator
    订阅到netvibes

    转载 使用NetBeans进行J2ME开发(三):低级图形用户界面Canvas 收藏

    新一篇: 使用NetBeans进行J2ME开发(五):揭开游戏开发的神秘面纱  | 旧一篇: NetBeans vs Eclipse 之性能参数对比

    在这一篇中,我将向大家介绍图形用户界面中的低级图形用户界面。所谓低级图形用户界面,指的是那种我们可以自己在上面画图的控件,它是和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

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

    发表于 @ 2008年02月21日 11:43:00|评论(loading...)|编辑

    新一篇: 使用NetBeans进行J2ME开发(五):揭开游戏开发的神秘面纱  | 旧一篇: NetBeans vs Eclipse 之性能参数对比

    评论:没有评论。