J2ME在移动设备上的动画解决方案
任何动画的最基本前提是在足够快的时间内显示和替换图片,使人们能够看到运动画面的效果。
要做的第一件事是用你的图片处理(如PS或烟花)创造了一系列的相同尺寸的图像形成动画。每幅图代表一帧的动画,你需要一定数量的帧帧动画更会让你看起来更光滑,产生图片必须保存在PNG(便携式网络图形)格式和图像格式支持MIDP。
有两种方法可以让你刚刚做的成为动画在MIDlet的照片。首先,把所有的照片都放在网上,让MIDlet下载,MIDP的内置支持断点续传。二是更简单,和图片打包成jar文件的程序。如果您使用的是J2ME开发工具,把PNG文件在你的项目文件。
动画的过程其实更像本书记录:显示当前帧,然后到下一帧的相应的变化,所以它是适当的使用一个类来做到这一点,好吧,让我们先定义一个animatedimage类:
导入java。利用*;
进口javax.娘的*程序;
定义一个动画,动画实际上是一系列相同大小的动画。
然后进行动画显示。
公共课animatedimage延伸TimerTask {;
帆布帆布;
专用图像{ }图像;
{ } { } cliplist私有;
私人INT电流;
私有数组;
私有整数;
私人域名;
私有整数;
没有画布的动画。 /构建
市民AnimatedImage(图像{ }图片){;
此(NULL,图像,NULL);
};
用空/剪辑列表构建动画。
市民AnimatedImage(canvas画布,图像{ }图片)
{;
此(画布,图像,NULL);
};
构建动画。画布可以是空的,
但是,如果不为空则会触发/油漆
每次它都会由于计时器而改变图像。
如果剪辑列表是事件。指定的图像是
多次重复,每次使用不同的
来模拟/裁剪矩形,透明部分。
市民AnimatedImage(canvas画布,图像{ } { } { }图像,int cliplist){;
this.canvas =帆布;
this.images =图像;
this.cliplist = cliplist;
如果(图像)!= null cliplist!= NULL){;
如果(cliplist.length抛出时()();
};
};
如果(图像)!= null images.length > 0){;
W =图像{ 0 }。getWidth();
H =图像getHeight(){ 0 };
};
};
到下一个移动框,如果需要包装。
公共无效推进(布尔重画){;
如果(+当前=图像长度){;
电流=0;
};
如果(重画帆布!= null canvas.isshown()){;
Canvas.repaint(X,Y,W,H);
canvas.servicerepaints();
};
};
在动画中绘制当前图像。如果
只需要剪辑一个简单的副本,否则
相应地剪裁矩形并设置
图像多次。
公共空绘制(图形G){;
如果(W = 0 | | H = = 0)返回;
int =当前;
如果(cliplist = = null | | { cliplist { } = = null);
G.drawImage(图片{ },X,Y,
G.TOP g.LEFT |);
};其他{;
g.getclipx CX = int();
int cy = g.getclipy();
g.getclipwidth CW = int();
g.getclipheight CH = int();
int { } { } = cliplist列表;
为(int i = 0;我+ 3 g.setclip(X + Y +列表{ 0 },{ 1 }名单列表,列表{ 2 },{ 3 });
G.drawImage(图片{ },X,Y,
G.TOP g.LEFT |);
};
g.setclip(CX,CY,CW,CH);
};
};
动画的左上角。
公共无效移动(int x,int y){;
这个;
这个,y = y;
};
由计时器调用。前进到下一帧
造成重如果 /帆布指定。
公共空运行(){;
如果(W = 0 | | H = = 0)返回;
U3000
前进(正确);
};
};
当你实例化一个animatedimage对象,你必须传递图像对象的animatedimage类施工方法的数组,它代表每帧动画。所有的图片都必须使用相同的高度和宽度。
使用image.createimage()从JAR文件加载图像的方法:
私人形象{ } loadframes(String name,int帧)
抛出IOException {;
图像{ }图像=新图像{帧};
为(int i = 0;我的形象= image.createimage(姓名+我+PNG);
};
返回图像;
};
你也可以通过画布对象(可选),和剪辑列表(剪辑列表)。如果你指定一个画布,用定时器来自动换到下一帧的动画,如下面的示例代码,前滚后在动画自动重绘油画(重画)。但这一方法的实现是可选的,你可以做,也可以让程序选择合适的时间重绘油画。
因为MIDP 1不支持透明的图片。的animatedimage类使用剪辑列表对透明度的影响。剪辑列表是一系列的块状区域,图片裁剪。图片是分开几次当画画,每次画一个裁剪区域内夹列表。剪辑列表是在框架的基础上定义的,所以你需要创造画面的每一帧数组。数组的大小应该是4的倍数,因为每个剪辑区域保持四个值:左上坐标,坐标、宽度和高度,坐标原点是整张照片的左上角。需要注意的是,使用剪辑列表会缓慢的动画重要。如果画面比较复杂,你应该使用一个矢量图。
的animatedimage类扩展了java.util.timertask,允许你设置一个定时器。这里的一个例子,如何激活使用定时器:
定时器定时器=新定时器();
animatedimage AI =图像 / /得到.....
Timer.schedule(AI,200, 200);
每200毫秒定时器调用AnimatedImage.run()方法一次,使动画滚动到下一帧,现在我们需要的是有程序尝试显示动画!我们定义了一个简单的画布类的子类,这样我们就可以粘贴动画了。
导入java。利用*;
进口javax.娘的*程序;
一种可以附加一个或多个的画布。
动画图片。当画布被绘制时,
它通过动画图像循环/请求
描绘他们当前的形象。 /它们
公共课animatedcanvas延伸帆布{;
专用显示器;
私人后台图像;
私有向量图像=新向量();
公共animatedcanvas(显示){;
this.display =显示;
如果画布不是双/缓冲的
自己动手做…
如果(!isdoublebuffered()){;
画外= image.createimage(getWidth()),
GetHeight());
};
};
将动画图像添加到列表中。
公共无效添加(animatedimage图像){;
images.addelement(图像);
};
通过擦除屏幕来绘制画布,然后
依次绘制每个动画图像。双
用于减少闪烁。缓冲
保护空白油漆(图形G){;
图形保存= G;
如果(画外音!= NULL){;
G = offscreen.getgraphics();
};
(255, 255, 255)g.setcolor;
g.fillrect(0, 0,getWidth(),getHeight());
int n = images.size();
为(int i = 0;我animatedimage img =(animatedimage))
Images.elementAt(我);
img.draw(G);
};
如果(g)!=已保存){;
Saved.drawImage(画外,0, 0,
Graphics.LEFT Graphics.TOP |);
};
};
};
该animatedcanvas类的代码是很简单的,一个动画导入方法和涂料的方法。帆布帆布画一次,背景将被删除,然后每个周期的animatedimage对象直接向自己(他把画布类)。
导入java IO *;
导入java。利用*;
进口javax.娘的*程序;
进口javax.娘的MIDlet。*;
显示一些简单的动画。 / /程序
在屏幕上显示一系列的鸟
他们在 / /动画不同(随机)率。
公共课animationtest扩展MIDlet
实现了CommandListener {;
私有静态最后bird_frames = 7;
私有静态最后num_birds = 5;
专用显示器;
专用计时器=新定时器();
私人animatedimage { }鸟;
私有随机数=新随机数();
public static final的命令exitcommand =新的命令(退出
Public AnimationTest () {;};
public void commandAction(命令C,可显示D){;
如果(C = = exitcommand){;
ExitMIDlet();
};
};
protected void destroyapp(布尔条件)
把midletstatechangeexception {;
ExitMIDlet();
};
公共无效exitmidlet(){;
(定时器取消)…
notifydestroyed();
};
非负随机数…
私有genrandom(国际上){;
返回(math.abs(random.nextint())%上);
};
公共显示getDisplay(){ };显示;
通过创建画布来初始化事物,然后
创造一系列的鸟被移动到
画布上的随机位置和/附加到
调度计时器。
initmidlet protected void(){;
尝试{;
animatedcanvas C =新
AnimatedCanvas(getDisplay());
{ }图像图像= loadframes( / /鸟图片
W = c.getwidth int();
H = c.getheight int();
鸟=新animatedimage { num_birds };
为(int i = 0;我AnimatedImage B =新)
AnimatedImage(C,图像);
鸟=乙;
B.move(genrandom(W),genrandom(H));
C.add(B);
Timer.schedule(B,genrandom(1000),genrandom(400));
};
c.addcommand(exitcommand);
C.setCommandListener(本);
GetDisplay()SetCurrent(C);
};
赶上(IOException e){;
System.out.println(无法加载图像);
ExitMIDlet();
};
};
作为一个存储的
系列png文件在/ MIDlet套件。
私人形象{ } loadframes(String name,int帧)
抛出IOException {;
图像{ }图像=新图像{帧};
为(int i = 0;我的形象= image.createimage(姓名+我+PNG);
};
返回图像;
};
protected void pauseApp(){;};
protected void startApp()
把midletstatechangeexception {;
如果(显示= NULL){;
显示= display.getdisplay(本);
InitMIDlet();
};
};
};
七帧的动画,你可以用wings.midlet显示5鸟看鸟,和鸟的位置和速度是随机的。你可以用一些其他的方法来提高程序的,但它足以让你得到。