Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1561073
  • 博文数量: 3500
  • 博客积分: 6000
  • 博客等级: 准将
  • 技术积分: 43870
  • 用 户 组: 普通用户
  • 注册时间: 2008-05-03 20:31
文章分类

全部博文(3500)

文章存档

2008年(3500)

我的朋友

分类:

2008-05-04 19:14:14

一起学习
教 学 纲 要

Java 世界 里 最 激 动 人 心 的 时 刻 终 于 到 来 了 , 在 这 一 章 里 你 将 学到 在 主 页 里 播 放 动 画 的 技 巧 , 以 及 载 入 和 播 放 声 音 的 方法 , 掌 握 了 本 章 所 讲 授 的 这 些 技 巧 , 再 加 上 你 脑 子 里 各种 希 奇 古 怪 的 念 头 , 你 就 有 能 力 创 造 出 你 自 己 的 真 正 活灵 活 现 、 有 声 有 色 的 活 动 Web 主 页 来 。

正 文

  • 学 习 动 画 原 理
  • 了 解 多 线 程 的 工 作 过 程
  • 利 用 多 线 程 制 作
  • 在 动 画 里 加 入 背 景 音 乐
    想 像 一 下 , 当 别 人 正 在 浏 览 你 的 主 页 时, 突 然 有 个 小 丑 向 他 做 了 个 鬼 脸 , 跑 出 一 只 甲 虫 在 你 的主 页 上 载 歌 载 舞 , 或 者 不 知 道 从 哪 里 冒 出 点 儿 声 儿 来 吓他 一 跳 , 那 将 是 多 么 让 人 欣 喜 的 事 情 。 这 也 正 是 Java 的迷 人 之 处 , 它 能 在 你 不 注 意 的 时 候 给 你 一 个 惊 喜 。 如 今我 们 到 处 都 能 听 到 或 看 到 所 谓 活 动 Web 主 页 ( Live Web Page ) , 是 不 是 很 吸 引 人 呢 ?



孙 悟 空 的 筋 斗 是 怎 么 翻出 来 的 ?






    我 们 知 道 电 影 是 一 张 张 电 影 胶 片 在 放映 机 前 滚 过 , 在 银 幕 上 投 影 出 动 态 的 画 面 , 动 画 片 是 由一 组 差 异 很 小 的 图 片 组 合 在 一 起 , 快 速 地 切 换 这 些 图 片, 你 所 看 到 的 就 是 一 个 在 翻 跟 头 的 孙 悟 空 。 那 么 计 算 机上 的 动 画 也 是 这 样 做 出 来 的 吗 ? 基 本 原 理 差 不 多 。 首 先要 有 一 组 连 续 动 作 的 图 片 , 然 后 只 需 要 快 速 地 用 这 一 组图 片 顺 序 刷 新 显 示 器 上 的 画 面 就 可 以 看 到 一 张 张 静 态 的画 面 变 成 一 段 可 爱 的 动 画 片 段 了 。

    所 以 用 Java 来 实 现 动 画 实 在 是 再 简 单 不过 了 , 你 肯 定 马 上 就 想 到 了 前 面 已 经 学 过 的 加 载 和 显 示图 片 。 既 然 制 作 动 画 最 基 本 的 两 个 步 骤 你 都 会 了 , 那 还有 什 么 能 难 得 住 你 呢 ? 现 在 你 已 经 会 用 getImage 把 一 个 图形 文 件 加 载 到 Java 程 序 中 , 并 用 drawImage 把 加 载 进 来 的 图片 输 出 到 你 的 Applet 窗 口 中 。 ( 如 果 getImage 和 drawImage 这两 个 方 法 你 忘 了 的 话 , 请 参 阅 第 十 二 章 。 ) 问 题 是 在 这一 章 中 我 们 将 加 载 的 不 是 单 张 的 图 片 , 而 是 一 组 图 片 ,并 依 次 每 隔 一 段 时 间 就 显 示 一 张 。 我 们 怎 么 控 制 它 什 么时 候 该 换 掉 旧 的 显 示 新 的 呢 ? 问 得 好 ! 这 就 是 下 面 要 讲的 问 题 。

    动 画 效 果 的 好 坏 不 仅 仅 取 决 于 画 面 是否 漂 亮 , 而 且 还 取 决 于 动 画 中 动 作 的 平 滑 程 度 。 我 们 当然 不 希 望 看 到 自 己 主 页 里 的 动 画 动 起 来 像 僵 硬 的 木 偶 ,要 让 你 的 动 画 看 上 去 动 作 连 贯 平 滑 就 需 要 控 制 切 换 图 片的 速 度 。 可 想 而 知 , 相 同 时 间 内 放 映 的 图 片 张 数 越 多 ,动 画 中 人 物 的 动 作 看 上 去 就 越 平 滑 。

    那 么 Java 到 底 靠 什 么 来 决 定 何 时 显 示 图片 、 何 时 更 换 图 片 呢 ? 当 然 是 时 钟 。 每 台 计 算 机 内 部 都有 一 个 很 精 确 的 时 钟 , 计 算 机 依 赖 它 才 能 有 条 不 紊 地 进行 工 作 。 我 们 可 以 对 显 示 的 每 一 帧 图 片 计 时 , 一 到 规 定时 间 就 把 它 撤 换 掉 , 定 时 地 顺 序 地 替 换 组 成 动 画 的 每 一帧 画 面 , 画 不 就 动 起 来 了 吗 ? 那 我 们 用 什 么 来 计 时 呢 ?线 程 ! 这 是 最 好 的 解 决 办 法 。 支 持 多 线 程 也 是 Java 的 一大 特 征 。



什 么 是 线 程 ?






    " 线 程 ” 这 个 词 似 乎 听 说 过 。 其 实 它 的确 也 没 有 什 么 神 秘 的 , 线 程 就 是 执 行 中 的 一 段 程 序 。 举个 生 活 中 的 例 子 : 生 活 中 很 多 事 情 都 可 以 看 作 是 线 程 ,比 如 吃 饭 、 睡 觉 、 看 书 、 工 作 … … 有 时 候 为 了 提 高 效 率, 你 可 能 会 同 时 做 几 件 事 , 每 一 件 事 叫 做 一 个 线 程 , 那么 你 就 工 作 在 多 线 程 状 态 下 了 。 假 设 你 正 在 准 备 晚 餐 ,微 波 炉 里 正 烤 着 面 包 , 咖 啡 壶 里 正 煮 着 咖 啡 , 你 也 许 正在 煤 气 灶 边 忙 着 煎 鸡 蛋 。 你 得 不 时 地 关 照 着 微 波 炉 和 咖啡 壶 , 还 得 注 意 不 要 把 蛋 煎 糊 了 , 如 果 电 话 铃 响 了 , 你还 得 把 电 话 夹 在 腋 窝 下 接 电 话 。 那 我 要 说 你 简 直 是 个 效率 专 家 , 你 正 在 完 成 多 线 程 任 务 。

图 18.1 什 么 是 多 线 程

    其 实 Java 就 是 一 种 能 让 CPU 忙 得 团 团 转的 语 言 , 因 为 它 支 持 多 线 程 。 它 可 以 让 CPU 同 时 从 从 网 络上 读 取 数 据 、 等 待 用 户 的 输 入 、 在 屏 幕 上 显 示 动 画 , 并且 向 打 印 机 发 出 打 印 指 令 。 你 看 Java 通 过 它 的 多 线 程 机制 大 大 地 提 高 了 CPU 的 工 作 效 率 。

    既 然 多 线 程 是 这 么 一 个 好 东 西 , 我 们何 不 利 用 它 呢 。 听 起 来 似 乎 挺 复 杂 , 其 实 使 用 多 线 程 的过 程 很 简 单 。 只 要 遵 循 固 定 的 步 骤 , 一 步 步 地 在 程 序 里加 入 我 们 想 做 的 事 情 就 可 以 了 。     1.用 你 所 编 的 Applet 去 实 现 Runnable 接 口 。
    2.在 方 法 start 中 产 生 一 个 新 的 工 作 进程 。
    3.在 方 法 stop 中 编 写 结 束 线 程 要 处 理 的事 情 。
    4.加 一 个 run 方 法 , 在 这 个 方 法 中 写 你想 让 新 产 生 的 那 个 线 程 做 的 事 情 , 其 实 就 是 给 新 线 程 分配 任 务 。

    哦 ! 我 又 糊 涂 了 , 又 是 线 程 , 又 是 方法 , 还 有 什 么 接 口 。 我 们 下 面 就 一 步 一 步 地 讲 。

第 一 步 : 让 你 的 Applet 实 现 Runnable 接 口 。

    这 并 不 难 理 解 , 我 们 可 以 把 每 个 程 序看 作 一 个 线 程 , 它 从 开 始 到 结 束 只 能 干 一 件 事 。 如 果 你想 让 它 同 时 干 两 件 事 , 就 必 须 在 原 来 那 个 程 序 里 加 上 Runnable 接 口 以 便 让 连 贯 线 程 能 够 同 时 工 作 。 举 个 例 子 来 说 , 一个 电 源 插 座 上 只 能 插 一 个 电 器 , 如 果 你 正 在 看 电 视 , 就不 能 使 用 录 像 机 , 可 是 你 想 把 好 看 的 节 目 录 下 来 , 非 用录 像 机 不 可 , 怎 么 办 呢 ? 聪 明 的 你 马 上 就 想 到 加 一 个 插线 板 问 题 就 解 决 了 。 在 这 里 Runnable 接 口 就 是 线 程 的 插 线板 , 只 要 你 的 Applet 实 现 了 Runnable 接 口 , 它 就 可 以 成 为 多线 程 程 序 了 , 而 且 实 现 Runnable 接 口 也 的 确 和 加 一 个 插 线板 一 样 简 单 , 你 只 需 要 这 样 写 :     public class cartoon extends java.applet.Applet  implements Runnable { … … }
这 句 话 的 前 面 一 部 分 , 我 们 都 已 经 很 熟 悉了 , cartoon 是 你 的 Applet 的 名 字 , implements Runnable 就 是 咱们 的 插 线 板 。

第 二 步 : 在 Start 方 法 里 产 生 一 个 新 的 线 程。

    在 Java 里 线 程 也 被 当 作 一 个 类 。 类 Thread 封 装 了 所 有 有 关 线 程 的 控 制 , 用 来 控 制 线 程 的 运 行 、 睡眠 、 挂 起 和 中 止 。 Thread 类 是 唯 一 可 以 用 来 控 制 线 程 的 手段 。 start 的 实 现 很 简 单 。
    public void start ( )
    {    if (thread1 == null )
        {    thread1 = new Thread ( this ) ;
            thread1. start ( ) ;
        }
    }
方 法 start 里 产 生 了 一 个 新 的 进 程 , 当 start( ) 执 行 完 以 后 , 程 序 里 就 有 了 两 个 线 程 在 同 时 工 作 , 一个 是 原 来 的 程 序 , 另 一 个 则 是 由 start( ) 产 生 的 , start( ) 中 产 生 的 这 个 线 程 完 成 下 面 将 谈 到 的 方 法 run 中 指 定 的 任务 。

第 三步 : 在 方 法 stop( ) 里 把 start( ) 产 生 的 一 个 线 程 关 掉 , 中止 线 程 的 工 作 , 并 释 放 线 程 , 用 stop 中 止 的 线 程 将 不 能再 启 动 , 也 就 是 说 这 个 线 程 已 经 死 了 , 所 以 应 该 释 放 它。 Stop 方 法 应 该 这 样 写 :
    public void stop ( )
    {    thread1.stop ( ) ;
        thread1 = null ;    }

第 四 步 : 在 run( ) 方 法 里 给 新 产 生 的 进 程 分配 任 务 。

    run 是 线 程 的 核 心 , 在 这 个 方 法 里 , 我们 将 写 入 新 线 程 工 作 的 程 序 代 码 , 告 诉 这 位 新 来 的 线 程先 生 该 做 什 么 。 事 实 上 你 可 以 在 方 法 run 里 做 任 何 你 想 做的 事 情 , 原 来 的 那 个 线 程 并 不 会 因 为 它 而 受 到 什 么 影 响, 因 为 它 们 是 两 个 完 全 独 立 的 线 程 , 互 不 干 扰 。 这 里 还要 提 一 句 , 除 了 stop 可 以 中 止 线 程 的 工 作 外 , run 中 的 程序 代 码 一 旦 执 行 结 束 , 线 程 也 会 自 动 中 止 。

    好 啦 ! 讲 了 这 么 多 , 不 知 道 你 清 楚 了没 有 ? 如 果 你 还 是 觉 得 云 山 雾 罩 , 没 有 关 系 , 只 要 你 照着 这 四 个 步 骤 一 步 步 来 , 你 仍 然 能 很 容 易 写 出 一 个 像 模像 样 的 多 线 程 程 序 来 。 下 面 就 让 我 们 来 试 试 吧 。



翻 筋 斗 的 小 企 鹅

    这 一 章 不 是 讲 动 画 吗 ? 怎 么 又 讲 这 么一 大 堆 线 程 的 东 西 ? 这 是 因 为 要 编 出 一 个 好 的 具 有 动 画效 果 的 Java 程 序 , 就 必 须 利 用 线 程 。 所 以 前 面 我 们 是 在为 这 一 节 打 基 础 , 现 在 我 们 已 经 知 道 怎 样 启 动 和 中 止 一个 线 程 , 怎 样 在 方 法 run 中 指 定 线 程 工 作 。 那 么 就 把 它 用到 咱 们 的 动 画 程 序 里 来 吧 !
程 序 18.1 // animate.java
import java.awt.*;

public class animate extends java.applet.Applet implements Runnable        // 实 现 Runnable 接 口
{
    Image frame[ ];            // 说 明 一 个 Image 数 组 , 准 备 放 动 画 图 片
    Thread thd;            // 说 明 一 个 Thread ( 线 程 ) 对 象
    int num;            // 设 置 计 算 帧 数的 计 数 器
    int pause;            // 设 置 每 帧 显 示的 时 间

    public void init( )
    {
        String fps;            // 设 置 每秒 切 换 图 片 的 张 数
        frame = new Image[17];    // 构 造 Image 数 组 , 共 包 含 17 个 元 素
        thd = null;                // 初始 化 线 程
        num = 0;            // 计 数 器 置 0
        for (int i = 0; i < frame.length; i )   // 加 载 图 片
        frame[i] = getImage(getCodeBase( ), "images/T" i ".gif");
        fps = getParameter("speed");    // 从 HTML 文 件 读 入 参 数 speed , 确 定 放 映 速 度
        if (fps == null)    // 如 果 HTML 中 未指 定 参 数 , 则 用 省 缺 的 放 映 速 度
        fps = "10";            // 为 每 秒 10 帧
        pause = 1000 / Integer.parseInt(fps);    // 计 算 每 帧 图 片 显 示 的 时 间
    }
    public void start( )
    {
        if (thd == null)
        {
            thd = new Thread(this);    // 在 start( ) 方 法 里 产 生 一 个 新 线 程 , 名 为 thd
            thd.start( );        // 启 动 这个 新 线 程
        }
    }
    public void stop( )
    {
        if (thd != null)
        {
            thd.stop( );        // 在 stop( ) 方 法 里 中 止 线 程 thd
            thd = null;        // 释 放 线程         }
    }
    public void run( )
    { while (true)
        { try { Thread.sleep(pause); }    // 让线 程 睡 眠 每 一 帧 图 片 的 显 示 的 时 间
        catch (InterruptedException e) {}
        repaint( );            // 重 画 窗口
        num = (num 1) % frame.length;    // 计数 器 增 1
        }
    }
    public void paint(Graphics g)
    {
        g.drawImage(frame[num], 0, 0, this);    // 显 示 计 数 器 指 定 的 那 帧 图 片
    }
    public void update(Graphics g)
    {
        paint(g);
    }
}
该 程 序 的 HTML 文 件 如 下 所 示 :

< HTML>
< HEAD>
< TITLE>animate< /TITLE>
< /HEAD>
< BODY>
< APPLET CODE = "animate.class" WIDTH = 130 HEIGHT = 80>
< param name = "speed" value = "5">
< /APPLET>
< /BODY>
< /HTML>

下载本文示例代码


第十八讲 动画制作及声音载入(一)第十八讲 动画制作及声音载入(一)第十八讲 动画制作及声音载入(一)第十八讲 动画制作及声音载入(一)第十八讲 动画制作及声音载入(一)第十八讲 动画制作及声音载入(一)第十八讲 动画制作及声音载入(一)第十八讲 动画制作及声音载入(一)第十八讲 动画制作及声音载入(一)第十八讲 动画制作及声音载入(一)第十八讲 动画制作及声音载入(一)第十八讲 动画制作及声音载入(一)

阅读(368) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~