随笔-30  评论-123  文章-0  trackbacks-0


第三章 用精灵实现动画 

屏幕快照
在这一章你将创建你的第一个 MIDlet 程序来学习如何用精灵来创建简单的动画。 ( 8) 展示了模拟器上运行的完整的 MIDlet
程序的一系列屏幕快照。
o_8.jpg(图8)

螺旋运动的精灵
我们的 MIDlet 程序的精灵如 ( 9) 所示:
o_9.jpg(图9)
这个精灵由44列,16张独立的帧组成。每一帧按次序显示以创建动画效果。

创建精灵类:AnimationSprite.java

在本教程中,对于你要开发的每一个MIDlet程序,当使用Wieless Toolkit(WTK)开发时,都遵循一组相同的开发步骤:

1. 创建工程.

2. 书写源代码.

3. 编译和预校验源代码.

4. 运行MIDlet.

创建工程

创建一个新的工程

1. 点击New Project.

2. 输入工程名和MIDlet类名,如(10)所示.

3. 点击Create Project.
r_10.jpg(图10)

编写代码:第一步

在这个MIDlet程序中你将发现3个源代码文件:

° AnimationSprite.java: 精灵类

° AnimationCanvas.java: 显示精灵的GameCanvas

° Animation.java: MIDlet程序启动和停止的代码

将下面的AnimationSprite.java代码拷贝粘贴到文本编辑器:
/*---------------------------------------------
* AnimationSprite.java
*----------------------------------------------
*/

import javax.microedition.lcdui.game.*;
import javax.microedition.lcdui.*;
public class AnimationSprite extends Sprite{
  
public AnimationSprite(Image image, int frameWidth, int frameHeight){
    
// 调用Sprite的构造函数
    super(image, frameWidth, frameHeight);
  }

}
当你创建了一个新工程, WTK 会为你创建适当的目录结构。本例中, WTK 创建了目录 C:\WTK20\apps\Animation 以及必要的子目录。将 AnimationSprite.java Java 源文件保存到 src 目录下 ( 如图 11) 所示:
r_11.jpg(图11)
注意:启动器盘符和WTK目录会根据Toolkit安装目录的不同而不同。

编写代码:第二步

把下面的AnimationCanvas.java的代码拷贝到文本编辑器中,把文件保存到上一节中的相同的目录下。
/*--------------------------------------------------
* AnimationCanvas.java
*-------------------------------------------------
*/

import javax.microedition.lcdui.game.*;
import javax.microedition.lcdui.*;
public class AnimationCanvas extends GameCanvas implements Runnable{
    
// 一帧精灵图像的尺寸
    private static final int FRAME_WIDTH = 57;
    
private static final int FRAME_HEIGHT = 53;
    
private AnimationSprite spSpiral; // 动画精灵
    private LayerManager lmgr; // 图层管理器
    private boolean running = false// 线程是否启动
    public AnimationCanvas(){
        
// 游戏画布构造函数
        super(true);
        
try{
            
// 创建动画精灵
            spSpiral = new AnimationSprite(Image.createImage("/spiral.png");
            
// 将精灵的参考象素移到精灵的中间
            spSpiral.defineReferencePixel(FRAME_WIDTH / 2, FRAME_HEIGHT / 2);
            
// 将精灵放置在屏幕中心
            
// (精灵的中心和屏幕的中心重合)
            spSpiral.setRefPixelPosition(getWidth() / 2, getHeight() / 2);
            
// 创建图层管理器
            lmgr = new LayerManager();
            lmgr.append(spSpiral);
        }
catch (Exception e){
            System.out.println(
"Unable to read PNG image");
        }

    }

    
/*--------------------------------------------------
    * 启动线程
    *-------------------------------------------------
*/

    
public void start(){
        running 
= true;
        Thread t 
= new Thread(this);
        t.start();
    }

    
/*--------------------------------------------------
    * 主循环
    *-------------------------------------------------
*/

    
public void run(){
        Graphics g 
= getGraphics();
        
while (running){
            
// 刷新屏幕
            drawDisplay(g);
            
try{
                Thread.sleep(
150);
            }
 catch (InterruptedException ie) {
                System.out.println(
"Thread exception");
            }

        }

    }

    
/*--------------------------------------------------
    * 刷新屏幕
    *-------------------------------------------------
*/

    
private void drawDisplay(Graphics g){
        
// 显示下一帧精灵图像
        spSpiral.nextFrame();
        
// 绘制图层
        lmgr.paint(g, 00);
        
// 将屏幕缓冲刷新到屏幕
        flushGraphics();
    }

    
/*--------------------------------------------------
    * 停止线程
    *-------------------------------------------------
*/

    
public void stop(){
        running 
= false;
    }

}

编写代码:第三步
最后一部分代码如下所示。复制到文本编辑器中并另存为Animation.java:

/*--------------------------------------------------
* Animation.java
**
显示动画精灵
*-------------------------------------------------
*/

import javax.microedition.midlet.*;
import javax.microedition.lcdui.*;
public class Animation extends MIDlet implements CommandListener{
    
private Display display; 
    
private AnimationCanvas canvas; // 游戏画布
    private Command cmExit; // 退出按钮

    
public Animation(){
        display 
= Display.getDisplay(this);
        cmExit 
= new Command("Exit", Command.EXIT, 1);
        
// 创建游戏画布和退出按钮
        if ((canvas = new AnimationCanvas()) != null){
            canvas.addCommand(cmExit);
            canvas.setCommandListener(
this);
        }

    }


    
public void startApp(){
        
if (canvas != null){
        display.setCurrent(canvas);
        canvas.start();
        }

    }


    
public void pauseApp(){
    }


    
public void destroyApp(boolean unconditional){
        canvas.stop();
    }


    
public void commandAction(Command c, Displayable s){
        
if (c == cmExit){
            destroyApp(
true);
            notifyDestroyed();
        }

    }

}


编译和预校验
单击 Build 按钮完成编译、预校验和打包。入图 12 所示。然后点击 Run 启动应用管理器。
r_12.jpg(图12)

启动MIDlet
r_13.jpg(图13)
单击Launch启动Aninate MIDlet,如图13所示。启动以后你将会看到如图14所示的一系列屏幕输出画面。
o_8.jpg(图14)

代码回顾:创建精灵
让我们回去一下创建动画精灵的代码。这一节以及后面 3 节的代码片段均来自 AnimationCanvas.java. 文件

//  一帧精灵图像的尺寸
private   static   final   int  FRAME_WIDTH  =   57 ;
private   static   final   int  FRAME_HEIGHT  =   53 ;

//  创建动画精灵
spSpiral  =   new  AnimationSprite(Image.createImage( " /spiral.png " );

精灵通过一个已经存在的 PNG 文件创建。 FRAME_WIDTH FRAME_HEIGTH 表示图像中每一帧的宽度和高度。图 15 是同于创建精灵的实际图片,而图 16 把图像拆分成一个个独立的帧。
r_9.jpg(图15)r_16.jpg(图16)

代码回顾:设置参考像素
下面代码的第一行将精灵的参考像素移到了精灵的中间,紧接着调用setRefPixelPosition()将新的参考像素放置到设备屏幕的中心,最后的结果就是精灵的参考像素和设备屏幕的中心重合。

//  将精灵的参考象素移到精灵的中间
spSpiral.defineReferencePixel(FRAME_WIDTH  /   2 , FRAME_HEIGHT  /   2 );
//  将精灵放置在屏幕中心
//  (精灵的中心和屏幕的中心重合)
spSpiral.setRefPixelPosition(getWidth()  /   2 , getHeight()  /   2 );
//  创建图层管理器
lmgr  =   new  LayerManager();
lmgr.append(spSpiral);
上面代码的最后两行定义了一个图层管理器 ( layer manager ) 并且将精灵添加到管理器中。图层是游戏开发中的个基本的概念,它允许你灵活的将可视对象呈现在屏幕上。图层管理器处理图层的显示以确保图层能按适当层次显示到屏幕上。深入探讨图层的使用已经超出了本教程的范围,但是本教程却包含了创建 MIDlet 所需的全部知识。

代码回顾:运行动画
万事具备,下一步要做的就是开启一个线程,轮流画出精灵的图像帧。
    /*--------------------------------------------------
    * 启动线程
    *-------------------------------------------------
*/

    
public void start(){
        running 
= true;
        Thread t 
= new Thread(this);
        t.start();
    }

    
/*--------------------------------------------------
    * 主循环
    *-------------------------------------------------
*/

    
public void run(){
        Graphics g 
= getGraphics();
        
while (running){
            
// 刷新屏幕
            drawDisplay(g);
            
try{
                Thread.sleep(
150);
            }
 catch (InterruptedException ie) {
                System.out.println(
"Thread exception");
            }

        }

    }

线程运行时,
RUN()控制着多长时间更新一次屏幕。每一次循环运行到drawDisplay()就画出下一帧图像。下一节你将会看到drawDisplay()的内部细节。

代码回顾:画出图像帧
前面我们用FRAME_WIDTHFRAME_HEIGHT定义了帧的宽度和高度。利用这些信息MIDlet能够计算出图像中有多少帧图像。知道了有多少帧图像,nextFrame()就能恰当的循环遍历每一帧图像,并且当达到最后一帧时跳回到第一帧重新开始。
/*--------------------------------------------------
    * 刷新屏幕
    *-------------------------------------------------
*/

    
private void drawDisplay(Graphics g){
        
// 显示下一帧精灵图像
        spSpiral.nextFrame();
        
// 绘制图层
        lmgr.paint(g, 00);
        
// 将屏幕缓冲刷新到屏幕
        flushGraphics();
    }

图层管理器在指定位置绘制每一个图层,图层的位置取决于图层相对于屏幕的位置。在这个 MIDlet 中,你要求图层绘制在(0,0 )处。

如果你利用屏幕的顶部显示其他信息,例如显示分数,你可以改变传递给 Paint ()函数的 x,y 坐标值来适应这个要求。例如图 17 中,坐标设置在了( 17, 17 )处以便统计附加信息显示到屏幕顶部。这张图片直接从 Sun Microsystems MDIP2.0  API文档里截取而来。
o_17.jpg

                  to be continue...

posted on 2006-04-27 09:19 学二的猫 阅读(2737) 评论(6)  编辑  收藏 所属分类: J2ME

评论:
# re: 用Sprite编写J2ME程序--第三章 用精灵实现动画 2006-04-27 23:26 | 学二的猫
第四章正在加紧翻译,不日将与大家见面。希望大家多提宝贵建议和意见。  回复  更多评论
  
# re: 用Sprite编写J2ME程序--第三章 用精灵实现动画 2006-06-16 09:20 | mhrjxh
你的图片的每一帧的大小是如何得出的,57,53,如何根据自己的一个.png文件得出来,我运行你的程序为什么报不能加载图片呢?!我把png放在了classes路锦下的

  回复  更多评论
  
# re: 用Sprite编写J2ME程序--第三章 用精灵实现动画 2006-06-26 13:48 | 学二的猫
@mhrjxh
第一个问题:
57*53是大图片中的每一个组成帧的大小。并不是算出来的,而是事先就知道的。
第二个问题:
查看资源的路径是否正确。  回复  更多评论
  
# re: 用Sprite编写J2ME程序--第三章 用精灵实现动画 2007-08-20 15:05 | onlinewsz
@mhrjxh
我本来也是放在Classes路径下加载出错,后来我添加了个资源库把图片放里面,写上那个路径就OK了  回复  更多评论
  
# re: 用Sprite编写J2ME程序--第三章 用精灵实现动画 2008-04-16 16:37 | 青大
好东西要多分享啊
  回复  更多评论
  
# re: 用Sprite编写J2ME程序--第三章 用精灵实现动画[未登录] 2010-05-19 22:31 | l
@青大
spSpiral = new AnimationSprite(Image.createImage("/spiral.png");这行写错了。。   回复  更多评论
  

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


网站导航: