人气 202

[游戏程序] 游戏入门基础]DOS到Windows的 游 戏 移 植(3) [复制链接]

九艺网 2017-3-10 17:01:19

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?注册

x
键 盘 输 入

---- 在DOS 和Windows 两 个 版 本 的 Moby Dick 中, 我 们 都 保 持 了 一 个 键 状 态 表, 当 有 对 Move_Ahab 的 调 用 时, 该 表 能 够 告 诉 我 们 按 下 的 是 哪 一 个 光 标 键 或 数 字 键 盘 键。 但 是 在 Windows 版 中 我 们 不 能 使 用 键 盘 中 断 处 理 程 序 来 更 新 该 表---- 那 些 代 码 是 在 黑 箱 内 部 的, 不 允 许 我 们 打 开。
---- 为 此,Windows 给 我 们 提 供 了 两 种 跟 踪 键 盘 状 态 的 方 法---- 通 过 按 下 或 松 开 一 个 键 时 产 生 的 消 息, 或 通 过 函 数 调 用 来 检 查 键 盘 状 态。 让 我 们 来 看 看 如 何 用 这 两 种 方 法 在 Moby Dick 中 更 新 键 表。
响 应 消 息

---- 处 理 键 盘 输 入 的 最 明 显 的 方 法, 与 在 Moby Dick 的 DOS 版 的 中 断 处 理 程 序 中 所 使 用 的 方 法 类 似。 借 助 于 Windows 消 息 系 统 的 帮 助, 我 们 查 看 所 有 有 关 方 向 键 的 按 下 和 松 开, 并 做 出 响 应, 立 即 更 新 键 表。 当 然, 这 项 工 作 是 在 WM_KEYDOWN 和 WM_KEYUP 消 息 的 响 应 函 数 中 完 成 的---- 如 果 程 序 员 是 个“Windows 好 市 民” 的 话。
---- 这 种 方 法 的 问 题 是, 当 快 速 地 轻 敲 一 个 键, 那 么 这 个 键 的 状 态 也 许 会 在 被 Move_Ahab 查 询 之 前 便 已 返 回 到“ 未 按 下” 状 态 了; 换 句 话 说, 这 次 击 键 丢 失 了。 这 在 任 何 的 应 用 程 序 中 都 是 不 允 许 的, 在 游 戏 中, 有 可 能 玩 家 想 要 通 过 轻 敲 一 个 键 给 出 一 个 游 戏 动 作。
---- 一 种 解 决 方 法 是 在 程 序 中 保 持 键 的“ 按 下” 状 态 一 直 到 我 们 真 正 响 应 该 键 击。 只 当 接 收 到 WM_KEYDOWN 消 息 时 才 不 断 更 新 该 键 表, 而 不 处 理 WM_KEYUP 消 息。 而 在 Move_Moby 函 数 重 用 GetAsyncKeyState 来 检 查 各 键 当 前 是 否 是 按 下 的。 如 果 不 是, 在 表 中 清 除 该 键 的 项 目。
---- 虽 然 在 Moby Dick 中 我 们 不 是 这 样 做 的, 但 是 下 面 的 程 序 片 段 显 示 了 如 何 实 现 它:
---- LRESULT CALLBACK WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)

  1.                         ...



  2.   case WM_KEYDOWN:



  3.       switch( wParam )



  4.         {



  5.         case VK_LEFT:



  6.             key_table[INDEX_LEFT] = 1;



  7.             break;



  8.         // 对 于 其 它 键 同 样 处 理



  9.         ...



  10.       break;



  11. ...



  12.   }  // WindowProc 结 束







  13. int Move_Ahab();



  14.   {



  15.   ...



  16.   if (key_table[INDEX_LEFT])



  17.     {



  18.     AhabX--



  19.     if (!GetAsyncKeyState(VK_LEFT)) key_table[INDEX_LEFT] = 0;



  20.     }



  21.   // 对 于 键 表 的 其 余 部 分 同 样 处 理



  22.   ...



  23.   } // end of Move_Ahab



复制代码
检 查 键 盘 状 态

---- 但 是 实 际 上, 在 Moby Dick Windows 中 我 们 的 做 法 是: 如 果 我 们 想 要 使 用( 几 乎) 直 接 访 问 硬 件 的 GetAsyncKeyState, 我 们 同 时 越 过 消 息 系 统。
---- GetAsyncKeyState 有 一 个 方 便 之 处 是 它 的 返 回 值 中 包 含 两 项 信 息。 返 回 值 最 高 位 告 诉 我 们 该 键 现 在 是 否 是 按 下 的。 当 我 们 检 查 键 盘 时, 这 非 常 有 用, 但 是 在 这 之 间 的 时 间 段 怎 么 样, 即 我 们 如 何 保 持 快 速 的 键 击 不 被 丢 失 ? 那 就 是 返 回 的 信 息 中 另 一 项 的 作 用。 如 果 该 键 从 上 一 次 我 们 查 询 时 到 现 在 曾 经 被 按 下 过-- 就 算 它 现 在 未 被 按 下, 最 低 位 也 将 被 置 位。 所 以, 只 要 简 单 地 看 一 下 GetAsyncKeyState 的 非 零 的 返 回 值, 我 们 就 可 以 知 道 该 键 是 否 被 按 下, 或 者 自 它 上 次 被 调 用 后 是 否 被 按 下 过。( 当 然, 我 们 不 能 说 出 该 键 从 上 一 次 检 查 到 现 在 是 否 被 按 下 了 两 次, 但 是 游 戏 循 环 检 查 键 盘 的 速 度 足 够 快, 可 以 保 证 这 个 问 题 不 会 发 生。)
---- 在 API 参 考 中, 有 一 个 关 于 GetAsyncKeyState 的 重 要 事 情 没 有 被 详 细 的 解 释。 返 回 值 的 最 低 位 仅 由 一 个“ 正 式 的” 键 击 置 位-- 就 是 说, 只 有 在 考 虑 了 重 复 延 迟 和 重 复 速 率 的 用 户 设 置 值 之 后, 一 个 键 才 被 认 为 是 按 下 的。 如 果 您 在 编 写 一 个 字 处 理 应 用 程 序, 当 然 不 希 望 出 现“ ttthhhiiisss ” 这 样 的 情 况, 那 么 就 要 检 查 这 一 位。 很 显 然, 在 实 时 键 盘 处 理 中 我 们 不 能 仅 仅 依 靠 最 低 位 一 条; 如 果 我 们 这 样 做 的 话,Ahab 在 响 应 一 个 保 持 按 下 的 键 时 将 会 犹 犹 豫 豫 移 动 一 个 方 格, 然 后 以“ 控 制 面 板” 中 规 定 的 速 率 沿 一 个 方 向 继 续 前 进。 很 幸 运 的 时, 最 高 位 反 映 了 该 键 的 当 前 的、 未 经“ 翻 译” 的 状 态, 并 且 我 们 使 用 它 来 控 制 连 续 的 按 键。
---- 注 意: 当 应 用 程 序 处 于 后 台 时, 它 将 仍 然 保 持 工 作。 如 果 程 序 员 按 照“ 好 市 民” 的 方 式 跟 踪 键 盘, 那 么 就 无 须 为 此 担 心 什 么, 因 为 它 不 会 接 收 到 任 何 WM_KEYDOWN 或 WM_KEYUP 消 息。 但 是 如 果 程 序 员 直 接 管 理 键 盘, 就 算 用 户 在 其 它 应 用 程 序 中 击 键, 游 戏 还 是 会 处 理 每 一 次 击 键。 所 以 当 游 戏 失 去 输 入 焦 点 时, 一 定 要 关 闭 键 击 处 理。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

QQ|手机版|小黑屋|九艺游戏动画论坛 ( 津ICP备2022000452号-1 )

GMT+8, 2024-4-20 20:32 , Processed in 0.150994 second(s), 23 queries .

Powered by Discuz! X3.4  © 2001-2017 Discuz Team.