站内搜索: 请输入搜索关键词

当前页面: 开发资料首页Java 专题Java动画及自动浏览图片程序的开发

Java动画及自动浏览图片程序的开发

摘要: Java动画及自动浏览图片程序的开发



  本 文 介 绍 了Java 文 字 及 图 像 动 画 的 实 现 方 法, 并 讨 论 了 如 何 采 用 双 缓 冲 技 术 消 除 画 面 的 闪 烁 现 象, 在 此 基 础 之 上, 开 发 了 一 个 自 动 浏 览 图 片 程 序。

  Java 动 画 的 实 现, 首 先 用Java.awt 包 中Graphics 类 的drawImage() 方 法 在 屏 幕 上 画 出 图 像, 然 后 通 过 定 义 一 个 线 程, 让 该 线 程 睡 眠 一 段 时 间, 到 时 后 再 切 换 成 另 外 一 幅 图 像, 如 此 循 环, 从 而 达 到 显 示 动 画 的 目 的。

  文 字 动 画

  文 字 动 画 的 实 现 程 序 比 较 简 单, 首 先, 用new 方 法 创 建 一 个 新 进 程, 用drawString() 方 法 在 屏 幕 上 显 示 相 应 的 文 字, 然 后 让 进 程 睡 眠 一 定 时 间, 时 间 到 后, 改 变 文 字 显 示 位 置, 再 重 显 文 字。 其 中 包 含 一 个 边 界 判 断, 重 设 坐 标 的 过 程, 如 此 往 复 实 现 文 字 动 画。 程 序 运 行 后, 在 屏 幕 中 央 显 示" 欢 迎 进 入 动 画 世 界!", 每 隔0.15 秒 向 左 移 动 一 次, 直 到 屏 幕 最 左 端 又 重 新 开 始 显 示。 源 程 序 略。

  图 像 动 画

  图 像 动 画 的 实 现 方 法 与 文 字 相 似, 只 不 过 定 义 了 一 个Image 数 组, 运 用getImage() 方 法 装 载 相 应 图 像 文 件 到 该 数 组 中。 程 序 运 行 后, 可 见 到 一 个 可 爱 的 小 精 灵 在 作 抛 球 动 作。 另 外, 基 于 程 序 交 互 性 的 考 虑, 增 加 了 两 个 事 件 的 响 应 动 作, 一 个 是WINDOW_DESTROY, 即 关 闭 运 行 窗 口, 正 常 返 回。 另 外 一 个 是MOUSE_DOWN, 当 鼠 标 左 按 钮 按 下 时, 暂 停 线 程 以 便 让 画 面 静 止, 再 按 一 次 左 按 钮, 恢 复 暂 停 线 程, 继 续 显 示 下 一 幅 画 面。

  如 果 将 程 序 中 的 小 精 灵 图 像 文 件 换 成 图 片, 并 增 加 延 迟 时 间, 则 可 以 实 现 图 片 的 自 动 切 换, 变 为 自 动 浏 览 图 片 程 序。 源 程 序 略。

动 画 质 量 的 改 善

  上 一 程 序 的 运 行 后, 我 们 发 现 了 两 个 问 题。 第 一 是 程 序 在 图 像 完 全 加 载 之 前 就 开 始 显 示, 出 现 切 换 过 快 现 象。 第 二 是 画 面 闪 烁。

  对 于 前 一 个 问 题, 可 以 用Java.awt 包 中 的MediaTracker 类 来 解 决, 当StatusID() 方 法 返 回 值 为COMPLETE 时, 说 明 所 有 的 图 像 文 件 加 载 完 毕, 此 时 才 开 始 显 示 画 面。

  第 二 个 问 题 解 决 起 来 要 复 杂 一 些。 闪 烁 产 生 的 原 因 是, 在paint() 方 法 中 如 果 计 算 较 为 复 杂, 计 算 和 绘 制 画 面 的 时 间 超 过 了 屏 幕 的 刷 新 周 期, 则 帧 的 第 一 部 分 在 一 个 刷 新 周 期 中 绘 制, 其 余 部 分 在 下 一 个、 甚 至 更 后 的 周 期 绘 制, 这 样, 在 帧 的 不 同 部 分 之 间 产 生 时 间 间 隔, 由 此 造 成 闪 烁。 解 决 途 径 之 一 是 重 载update() 方 法,update() 的 缺 省 实 现 是 清 除 原 来 背 景, 然 后 调 用paint() 方 法。 因 此 通 过 重 载update(), 只 有 在 必 要 时 才 清 除 整 个 背 景。

  解 决 途 径 之 二 是 采 用 双 缓 冲 技 术, 双 缓 冲 技 术 是 在 后 台 图 形 区 内 创 建 一 个 图 形 对 象, 将 需 要 绘 制 的 图 像 绘 于 其 上, 然 后 传 给paint() 方 法, 由paint() 方 法 绘 于 前 台, 同 时, 后 台 图 形 缓 冲 区 进 入 下 一 帧 图 像 的 准 备。 下 图 为 双 缓 冲 技 术 示 意 图。

待显示的帧图像→后台图形缓冲区→前台图形缓冲区

  在 程 序 中 重 载 了update() 方 法 和paint() 方 法。 在update() 方 法 中, 在 后 台 缓 冲 区 建 立 了 一 图 形 对 象offScrGraphics:

Dimension d=size();

Image offScrImage=createImage(d.width,d.heigth);

Graphics offScrGraphics=offScrImage.getGraphics();



再 将 待 显 示 的 图 像 绘 于offScrGraphics 对 象 中:



offScrGraphics.drawImage(frames[I],0,0,this);



  在paint() 方 法 中, 将 绘 制 好 的offScrImage 图 像 绘 于 前 台 缓 冲 区:

g.drawImage(offScrImage,0,0,this);

  通 过 以 上 方 法, 很 好 地 消 除 了 画 面 闪 烁 现 象。

  需 要 注 意 的 是, 程 序 必 须 考 虑 内 存 空 间 的 大 小, 因 为 将 所 有 待 显 示 的 图 像 文 件 同 时 装 入 内 存 时, 往 往 会 占 用 很 大 的 空 间。 程 序 还 可 考 虑 意 外 出 错 的 处 理, 如 读 取 图 像 文 件 时 找 不 到 文 件 或 读 取 文 件 失 败 等。 还 可 以 将 文 字 动 画 和 图 像 动 画 结 合 起 来。

  所 有 程 序 在Windows95 下 的Visual J + + 1.0 中 运 行 通 过, 机 器 硬 件 配 置 为Pentium -II 200,32M 内 存。

  源 程 序 如 下:


//SimpleAnimation1.java 改 进 后 的 图 像 动 画 程 序
import java.awt. *;

public class SimpleAnimation1 extends Frame implements Runnable
{
Thread animation;
int frameDelay=1500;
int i=0;
Image frames[];
int numFrames=12;
int currentFrame=0;
int screenWidth=800;
int screenHeight=600;
boolean threadSuspended=false;
MediaTracker tracker;
Graphics offScrGraphics;
Dimension offScrDimension;
Image offScrImage;
String WellText=" 正 在 装 载 图 像, 请 稍 候 … …";
Font font=new Font(" 宋 体",Font.ITALIC,20);
public static void main(String args[])
{
SimpleAnimation1 app=new SimpleAnimation1();
}
public SimpleAnimation1()
{
setup();
resize(screenWidth,screenHeight);
show();
animation=new Thread(this);
animation.start();
}
void setup()
{
Toolkit t=getToolkit();
frames=new Image[numFrames];
tracker=new MediaTracker(this);
for(i=0;i{
String strImage="02_0" +(i<10?"0":"") +i +".gif";
frames[i]=t.getImage(strImage);
tracker.addImage(frames[i],i);
}
}
public void paint(Graphics g)
{

if(AllLoaded() & &(offScrImage!=null))
{
g.drawImage(offScrImage,0,0,this);
}
else
{
g.setFont(font);
g.setColor(Color.red);
g.drawString(WellText,150,100);
}
}
boolean AllLoaded()
{
for(i=0;i{
if(tracker.statusID(i,true)!=tracker.COMPLETE)
return false;
}
return true;
}

public void update(Graphics g)
{
Dimension d=size();
if((offScrGraphics==null)||(d.width!=offScrDimension.width)
||(d.height!=offScrDimension.height))
{
offScrDimension=d;
offScrImage=createImage(d.width,d.height);
offScrGraphics=offScrImage.getGraphics();
}
offScrGraphics.setColor(getBackground());
offScrGraphics.fillRect(0,0,d.width,d.height);
offScrGraphics.drawImage(frames[currentFrame],0,0,this);
if(AllLoaded())
{
g.drawImage(offScrImage,0,0,this);
}
}

public boolean handleEvent(Event event)
{
switch(event.id)
{
case Event.WINDOW_DESTROY:
stopAnimation();
System.exit(0);
break;
case Event.MOUSE_DOWN:
if(threadSuspended)
animation.resume();
else
animation.suspend();
threadSuspended=!threadSuspended;
}
return true;
}

public void stopAnimation()
{
if(animation!=null)
{
animation.stop();
animation=null;
}
}

public void run()
{
do{
if(AllLoaded() & &(offScrImage!=null))
{
repaint();
}
try{
animation.sleep(frameDelay);
}catch(InterruptedException e)
{
stopAnimation();
}
+ +currentFrame;
currentFrame %=numFrames;
}while(true);
}
}

↑返回目录
前一篇: 用Java实现Web服务器
后一篇: JAVA开发工具之英雄篇