动画的本质就是运动的图形,一系列连续显示的静止图形会给我 们一种连续动画的假象。只要动画速度足够快,则分散的静止图形就 会合并成一个连续运动的流程。
绘制动画十分简单,只需遵照以下三步即可:①擦去整个小程序绘 图区;②重画动画背景;③在新的位置绘制图形。但是,当动画连续帧 之间运动和颜色不连续时就会发生闪烁现象( 例子略)。问题出在小 程序区的屏幕刷新上,有两种方法可以防止动画闪烁。第一种方法是 只做局部刷新,即每次只擦除改变的部分。例如:如果要绘制一幅"飞 行的星空"动画,每次刷新操作,先擦去前一位置的星星,再在新的位置 绘制一个。但是,如果动画比较复杂,运动部分重叠较多,则局部刷新 操作很繁琐也影响程序运行速度。在这种情况下,可以用另外一种方 法( 双缓存)来解决闪烁问题。它的核心思想是在屏幕外完成一帧的 全部动画,然后把最后绘制完的帧显示在小程序屏幕上。过程如图3所 示。
示例程序如下:
import java.awt.*;
public class Ball extends MultiThreadApplet {
Image ball=null;
Image applet=null;
Graphics appletG,ballG;
public void run() {
if(ball==null) {
applet=createlmage(bounds().width, bounds().
height);
ball=create Image(70,70);
appletG=applet.getGraphics();
ballG=ball.getGraphics();
ballG.setColor(Color.gray);
ballG.drawOral(0,0,70,70); }
for(int x=0;x<400;x++) {
double angle=((double)x)/20;
int y=(int)(Math.abs(Math.sin(angle))*80);
appletG.clearRect(0,0,bounds().width.bounds(),
helght);
drawBackground(appletG);
appletG.drawImage(ball,x.80y,this);
this.getGraphics().drawImage(applet,0,0,this);
try {
Thread.sleep(25);
} catch(Exception ignored) { } }
}
private void drawBackground(Graphics g){
for (int i=0;i<1;i++){
g.drawLine(0.i* 10, 400,i*10); }
}
}
小程序首先用createImage()取得与小程序大小完全相同的屏外 图形缓存,赋给变量app let,然后得到缓存的绘图对象appletG。以后 对帧的刷新操作过程都是针对appletG。这包括清除帧、绘制背景、 在新位置绘制图形。最后再用drawImage()方法把缓存复制到小程序 的屏幕显示区。运行这个小程序,你会发现动画非常平滑,不存在闪烁 现象。
除了闪烁之外,如果动画过于复杂,帧速率就可能降低。若动画降 到每秒20帧,则动画会出现间断现象影响显示效果。因此有必要优化 动画速度,下面列出了一些可行的方案;①画得尽可能少;②用较快的 绘图算法;③用颜色循环等技巧来绘画某一部分;④用图案来表示细节 ;⑤用定点整数进行三维计算;⑥用查询的预先计算结果来处理复杂算 法。