Programming 版 (精华区)

发信人: superman (☆风雨无阻☆), 信区: Programming
标  题: [转载] DOS到Windows的 游 戏 移 植(3)
发信站: 紫 丁 香 (Sat Aug 29 07:35:42 1998), 站内信件

【 以下文字转载自 cnprogram 讨论区 】
【 原文由 Young_Yang@bbs.ustc.edu.cn 所发表 】

                    从DOS 到Windows 的 游 戏 移 植(3)
                                      
                                   谭 翁
                                      
     _________________________________________________________________
                                      
  键 盘 输 入
  
   ---- 在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)

....
  case WM_KEYDOWN:
      switch( wParam )
        {
        case VK_LEFT:
            key_table[INDEX_LEFT] = 1;
            break;
        // 对 于 其 它 键 同 样 处 理
        ...
      break;
....
  }  // WindowProc 结 束

int Move_Ahab();
  {
  ...
  if (key_table[INDEX_LEFT])
    {
    AhabX--
    if (!GetAsyncKeyState(VK_LEFT)) key_table[INDEX_LEFT] = 0;
    }
  // 对 于 键 表 的 其 余 部 分 同 样 处 理
  ...
  } // end of Move_Ahab

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

--
※ 来源: 中国科大BBS站 [bbs.ustc.edu.cn]
--
※ 转载:.紫 丁 香 bbs.hit.edu.cn.[FROM: poster.hit.edu.c]
[百宝箱] [返回首页] [上级目录] [根目录] [返回顶部] [刷新] [返回]
Powered by KBS BBS 2.0 (http://dev.kcn.cn)
页面执行时间:2.729毫秒