游戏入门基础]DOS到Windows的 游 戏 移 植(8) 

2007-01-08 10:56 发布

引擎学习交流 /[参考文档]
4269 0 0
在 本 系 列 文 章 的 前 面 几 部 分 中, 我 们 介 绍 了 一 个 简 单 的DOS 游 戏Moby Dick, 并 且 带 它 走 过 了 在 Win32 环 境 下 开 发 的 第 一 阶 段。 现 在, 我 们 将 对 该 游 戏 的 Windows 版 添 加 更 多 的 功 能: 立 体 声 效 果、MIDI 音 乐、TrueType 字 体、 和 用DirectDraw 图 形 实 现 的 透 明 效 果 的“ 捣 蛋 鬼”。

---- Moby Dick 只 是 为 Windows 95 编 写 的, 不 是 为 Windows NT。 同 时 因 为 该 游 戏 的 图 形 程 序 使 用 了 DirectDraw , 所 以 必 须 在 系 统 中 安 装 DirectX。

---- 所 提 供 的 可 执 行 文 件 使 用 了 DirectSound。 要 编 译 一 个 不 支 持DirectSound 的 版 本, 注 释 掉 文 件 MOBY.CPP 中 的 "#define USE_DIRECTSOUND" 一 行 即 可。 提 供 这 个 选 项 是 为 了 能 够 比 较 使 用 DirectSound 方 法 和 使 用 Windows 中 传 统 方 式 播 放 声 音 的 差 异。 这 里 对 主 游 戏 循 环 做 了 一 些 很 小 却 非 常 重 要 的 修 改。 在 以 前 的 文 章 中, 我 们 讲 述 了 在 实 时 游 戏 中 使 用 PeekMessage 好 处。 然 而,PeekMessage 循 环 会 大 量 消 耗 CPU 时 间, 即 使 该 应 用 程 序 是 处 于 后 台 并 且 理 论 上 没 有 做 任 何 事 情。 所 以, 当 Moby Dick 被 放 在 后 台 暂 停 执 行 时, 我 们 添 加 了 一 个 对 WaitMessage 的 调 用。 该 函 数 悬 挂 该 线 程, 直 到 在 队 列 中 出 现 一 个 消 息。

本 文 讨 论 声 音 的 处 理

从.VOC 到.WAV 的 转 变 ---- 有 多 种 免 费 软 件 和 共 享 实 用 程 序 可 以 将8 位 .VOC 文 件 转 换 为 .WAV 文 件; 可 以 查 阅 CompuServe 上 的 Windows AV 论 坛 (WINAV) 或 在 ftp://x2ftp.oulu.fi/pub/msdos/programming 站 点 上 的 大 量 与 编 程 有 关 的 文 章。 在 购 买 声 卡 时 也 可 能 得 到 了 这 样 的 实 用 程 序, 例 如 购 买 Sound Blaster 会 随 卡 奉 送 VOC2WAV.EXE。

使 用 PlaySound 播 放 声 音 ---- 将.WAV 文 件 编 译 到 可 执 行 程 序 中 并 播 放 的 步 骤 如 下:

---- 1. 从 一 个 .WAV 文 件 直 接 播 放 声 音。 要 使 Moby 有 声 音 的“ 喷 气”, 仅 需 写 一 行 代 码: PlaySound("blow.wav", NULL, SND_ASYNC | SND_FILENAME);

---- 其 参 数 是: (1) 文 件 名; (2) 包 含 该 资 源 的 程 序 模 块 句 柄, 我 们 用NULL 表 示 没 有 把 他 编 译 进 程 序 的 资 源 中, 因 为 我 们 没 有 使 用 一 个 已 编 译 的 资 源; (3) 标 志, 确 保 该 函 数 能 够 尽 可 能 快 的 返 回, 而 不 是 等 待 声 音 播 放 结 束, 并 且 指 明 第 一 个 参 数 是 文 件 名。 要 把 该 声 音 文 件 作 为 一 个 资 源 编 译 到 可 执 行 文 件 中, 需 要 在 资 源 (.RC) 文 件 中 添 加 下 面 一 行:

---- IDR_WAVE_BLOW WAVE "blow.wav"

---- IDR_WAVE_BLOW 是 在 头 文 件 RESOURCE.H 中 定 义 的 一 个ID。 WAVE 是 应 用 程 序 中 定 义( 主 观 命 名 的) 的 资 源 类 型。 声 音 与 图 标 和 位 图 不 同, 不 是 标 准 资 源, 所 以 必 须 分 配 一 个 类 型 名。

---- 当 需 要 从 资 源 中 播 放 声 音 时, 下 面 的 这 行 代 码 完 成 这 个 工 作:


			PlaySound(MAKEINTRESOURCE(IDR_WAVE_BLOW), hTheInstance, 



                SND_ASYNC | SND_RESOURCE);



---- 在 这 里, 第 一 个 参 数 是 资 源 名( 由 宏 MAKEINTRESOURCE 将 数 字 标 识 符 转 换 而 来)。 第 二 个 参 数 是 包 含 资 源 的 程 序 模 块 句 柄( 在 Moby 的 例 子 中 , 就 是 主 程 序 句 柄)。 最 后 面 的 标 志 已 经 被 改 变, 以 指 示 第 一 个 参 数 是 资 源 名 而 不 是 文 件 名。

使 用 DirectSound 播 放 声 音 ---- 在 游 戏 中 的 不 同 时 间 点 播 放 简 单 的 声 音, 使 用 PlaySound 就 足 够 了, 但 是 这 种 方 法 不 允 许 运 行 中 混 频 或 其 他 效 果。Windows API 的 多 媒 体 扩 展 中 有 一 组 函 数, 它 们 的 名 称 大 多 以 WAVE 开 头, 允 许 更 高 级 的 调 整, 但 是 这 些 都 被 DirectX Software Development Kit (SDK) 的 一 个 部 件 DirectSound 所 取 代。DirectSound 3 有 许 多 高 级 的 功 能, 包 括 自 动 混 频、3D 声 音( 在 双 声 道 系 统 模 拟“ 环 绕 音 响”) 和 立 体 声, 使 用 它 可 以 带 来 很 大 好 处。 DirectSound 不 提 供 幕 后 加 载 和 解 释 能 力, 而 这 些 功 能 PlaySound 都 提 供。 解 释 .WAV 文 件 是 程 序 员 的 责 任, 并 且 要 把 数 据 复 制 到 第 二 缓 冲 区( 第 二 缓 冲 区 在 后 台 保 持 数 据, 当 播 放 声 音 时, 这 些 数 据“ 流 入” 第 一 缓 冲 区。 程 序 员 无 须 考 虑 第 一 缓 冲 区 的 问 题, 它 由 DirectSound 保 持。) 示 例 工 程 在 文 件 WAVE.CPP 中 完 成 声 音 的 加 载 和 解 释, 声 音 数 据 是 从 一 个 资 源 加 载 的。 这 段 代 码 很 长, 所 以 在 这 里 就 不 引 述 它。 有 关 直 接 读 取 .WAV 文 件 的 简 单 代 码, 请 您 参 阅 有 关 文 章。

---- 一 旦 建 立 起 DirectSound 的 第 二 缓 冲 区, 事 情 就 又 变 得 简 单 了。 要 播 放 声 音, 只 需 调 用 DIRECTSOUNDBUFFER 对 象 的 Play 方 法 即 可:

---- lpDSB_Blow- > Play(0, 0, 0);

---- 在 当 前 版 本 的 DirectSound 中, 头 两 个 参 数 总 是 为 0 。 如 果 要 重 复 播 放 声 音, 可 以 把 第 三 个 参 数 设 置 为 DSBPLAY_LOOPING。

---- Moby Dick Windows 版 演 示 了 循 环 声 音, 以 及 当 两 个 .WAV 文 件 竞 争 时, 使 用 PlaySound 和 DirectSound 的 Play 方 法 的 不 同 结 果。 在 Settings 菜 单 中 打 开 声 音, 并 且 单 击 左 键 开 始 "boing" 声 音( 这 是 Queequeg 的 鱼 叉 的 声 音, 它 在 bungee 绳 索 上)。 使 用 右 键 停 止 声 音。 如 果 编 译 该 程 序 时 预 定 义 了 USE_DIRECTSOUND( 或 者 使 用 所 提 供 的 可 执 行 程 序),"boing" 和 Moby 的 沉 重 呼 吸 声 被 DirectSound 混 在 一 起 同 时 播 放。 如 果 没 有 定 义 USE_DIRECTSOUND,Moby 在 循 环 声 音 时 将 保 持 安 静, 因 为 PlaySound 在 同 一 时 间 只 能 做 一 件 事 情。

---- 下 面 您 介 绍 一 下 如 何 实 现 一 个 简 单 的 立 体 声 效 果。 假 设 有 一 个 立 体 声 的 声 卡, 在Moby 的 DirectSound 版 中, 鲸 鱼 的 有 声 的 吹 气 的 移 动 步 伐, 依 赖 于 气 流 的 方 向 是 朝 向 游 戏 屏 幕 的 右 边 还 是 左 边。Moby 每 呼 吸 一 次, 程 序 只 是 简 单 地 以 -10,000 到 10,000 的 为 度 量 计 算 其 相 对 的 东 西 位 置。 然 后 将 这 个 整 数 值 传 递 给 缓 冲 区 的 SetPan 方 法:

---- lpDSB_Blow- > SetPan(pan);

---- 这 一 操 作 在 Play 被 调 用 之 前 完 成。DirectSound 依 据 pan 的 从 0 开 始 的 划 分, 自 动 按 比 例 地 减 弱 一 个 声 道 或 另 一 个 声 道 的 回 放 声 音。 当 第 一 个 声 道 被 减 弱 时, 另 一 个 声 道 保 持 全 高 的 声 音。 换 句 话 说, 当 Moby Dick 位 于 其 世 界 的 死 角 时, 两 个 声 道 都 是 全 高 的 声 音; 当 它 走 到 最 东 或 最 西 边 时, 有 一 个 声 道 是 没 有 声 音 的。

播 放 MIDI 文 件 ---- Windows 通 过 多 媒 体 API 提 供 了 对 回 放 MIDI 文 件 的 高 级 和 低 级 支 持。 高 级 支 持 是 以 媒 体 控 制 接 口 (MCI) 函 数 的 形 式 提 供 的。 这 种 情 况 下, 使 用 MIDI 格 式 0 和 1 可 以 工 作, 但 是 MIDI 格 式 2 不 能 工 作。

---- MCI 函 数 实 际 上 可 以 有 两 种 不 同 的 调 用 方 法。mciSendString 函 数 使 用 看 起 来 不 象 计 算 机 代 码 的 字 符 串 命 令 来 控 制 MIDI 序 列 器(sequencer)( 或 其 他 任 何 的 媒 体 播 放 器)。 下 面 的 例 子 打 开 一 个 序 列 器, 并 且 读 要 回 放 的 文 件:


			mciSendString(



    "open song.mid type sequencer alias aria", 



lpszReturnString, lstrlen(lpszReturnString), NULL);



---- 该 调 用 定 义 了 文 件 名、 设 备 类 型 以 及 别 名( 在 示 例 中 是 "aria"), 它 可 用 于 后 续 的 调 用 中, 这 些 后 续 的 调 用 可 以 播 放、 暂 停 或 以 其 他 的 方 法 控 制 数 据 回 放。

---- 下 面 是mciSendCommand 的 列 出 顺 序:


			MCI_OPEN_PARMS  mciOpenParms;



MCI_PLAY_PARMS  mciPlayParms;



DWORD           dwReturn;







mciOpenParms.lpstrDeviceType = "sequencer";



mciOpenParms.lpstrElementName = "song.mid";



dwReturn = mciSendCommand(NULL, MCI_OPEN,



      MCI_OPEN_TYPE | MCI_OPEN_ELEMENT,



     (DWORD)(LPVOID) &mciOpenParms));



---- 在 MOBY.CPP 中, 读 者 可 以 看 到 mciSendCommand 的 一 个 简 单 实 现。 该 程 序 从 开 始 到 结 束 简 单 地 播 放 一 个 音 调, 同 时 Windows 操 作 系 统 发 送 一 条 消 息 到 该 应 用 程 序。 程 序 对 该 消 息 的 响 应 就 是 再 次 播 放 该 声 音。

---- 在 文 件 CGMIDI.CPP 中 演 示 了 一 个 播 放 MIDI 文 件 的 低 级 实 现 方 法, 这 个 程 序 在 DirectX SDK 的 "Immortal Klowns" 示 例 的 源 文 件 中 可 以 找 到。 这 个 示 例 没 有 使 用 MCI, 而 是 把 音 乐 文 件 加 载 到 内 存 中, 然 后 使 用 Windows MIDI 流 设 备 把 数 据“ 流” 到 MIDI 序 列 器 中,Windows MIDI 流 设 备 没 有 自 定 义 编 译 序 列 代 码 的 效 率 高, 但 是 比 MCI 的 效 率 高。 如 果 不 想 要 程 序 在 运 行 时 访 问 硬 盘 驱 动 器, 甚 至 访 问 CD-ROM, 预 先 加 载 数 据 是 一 个 好 方 法。

---- 在DOS 下, 使 用“ 流” 到 序 列 器 的 方 法 可 能 能 够 抢 救 大 多 数 现 存 代 码( 在 Windows 下 实 现 时 钟 时 允 许 不 同)。 但 是, 我 们 提 倡 使 用 CGMIDI.CPP 中 的 程 序, 无 论 是 否 修 改 它。

B Color Smilies

你可能喜欢

游戏入门基础]DOS到Windows的 游 戏 移 植(8) 
联系
我们
快速回复 返回顶部 返回列表