TA的每日心情 | 开心 2021-3-12 23:18 |
---|
签到天数: 2 天 [LV.1]初来乍到
|
屏幕快照
在这一章你将创建你的第一个 MIDlet 程序来学习如何用精灵来创建简单的动画。 ( 图 8) 展示了模拟器上运行的完整的 MIDlet 程序的一系列屏幕快照。

(图8)
螺旋运动的精灵
我们的 MIDlet 程序的精灵如 ( 图 9) 所示:

(图9)
这个精灵由4行4列,16张独立的帧组成。每一帧按次序显示以创建动画效果。
创建精灵类:AnimationSprite.java
在本教程中,对于你要开发的每一个MIDlet程序,当使用Wieless Toolkit(WTK)开发时,都遵循一组相同的开发步骤:
1. 创建工程.
2. 书写源代码.
3. 编译和预校验源代码.
4. 运行MIDlet.
创建工程
创建一个新的工程
1. 点击New Project.
2. 输入工程名和MIDlet类名,如(图10)所示.
3. 点击Create Project.
(图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:WTK20appsAnimation 以及必要的子目录。将 AnimationSprite.java 等 Java 源文件保存到 src 目录下 ( 如图 11) 所示:

(图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"),57,53) ;
// 将精灵的参考象素移到精灵的中间
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, 0, 0);
// 将屏幕缓冲刷新到屏幕
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 启动应用管理器。

(图12)
启动MIDlet

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

(图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 把图像拆分成一个个独立的帧。

(图15)

(图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 所需的全部知识。
代码回顾:运行动画
万事具备,下一步要做的就是开启一个线程,轮流画出精灵的图像帧。
线程运行时,RUN()控制着多长时间更新一次屏幕。每一次循环运行到drawDisplay()就画出下一帧图像。下一节你将会看到drawDisplay()的内部细节。
代码回顾:画出图像帧
前面我们用FRAME_WIDTH和FRAME_HEIGHT定义了帧的宽度和高度。利用这些信息MIDlet能够计算出图像中有多少帧图像。知道了有多少帧图像,nextFrame()就能恰当的循环遍历每一帧图像,并且当达到最后一帧时跳回到第一帧重新开始。
 /**//*--------------------------------------------------
* 刷新屏幕
*-------------------------------------------------*/
 private void drawDisplay(Graphics g) {
// 显示下一帧精灵图像
spSpiral.nextFrame();
// 绘制图层
lmgr.paint(g, 0, 0);
// 将屏幕缓冲刷新到屏幕
flushGraphics();
}
图层管理器在指定位置绘制每一个图层,图层的位置取决于图层相对于屏幕的位置。在这个 MIDlet 中,你要求图层绘制在(0,0 )处。
如果你利用屏幕的顶部显示其他信息,例如显示分数,你可以改变传递给 Paint ()函数的 x,y 坐标值来适应这个要求。例如图 17 中,坐标设置在了( 17, 17 )处以便统计附加信息显示到屏幕顶部。这张图片直接从 Sun Microsystems 的 MDIP2.0 API文档里截取而来。
源码下载:http://203.93.208.26/kj/cwb/dir7/Animation.zip |
|