# 给键盘输入一个明确的契约

> 通过选择语义键、处理按下和释放状态以及避免与浏览器默认值发生冲突，使键盘游戏玩法可预测。

- URL: https://oneshotgems.ai/zh-Hans/topics/keyboard-controls-for-games
- 类别: 游戏开发者指南
- 类型: 指南
- 更新日期: 2026年10月5日

当每个按键都有明确的功能并且游戏能够区分按下和按住的动作时，键盘控制感觉很可靠。在实现之前写下预期的映射：例如，箭头引导，空格键执行操作，而退出键仅在暂停菜单存在时打开该菜单。然后测试焦点、重复和释放行为，而不是仅验证单个按键。

## 按含义和布局选择按键

如果操作应对应用户键盘布局产生的字符，请使用 KeyboardEvent.key；如果更重要的是按键的物理位置，请使用 KeyboardEvent.code。不同键盘布局会影响两者的区别。提供统一的按键映射并写入说明，不要假设所有人都使用 WASD。

文本框或可编辑控件获得焦点时，不要拦截按键。只有当游戏区域确实处理该按键时，才阻止浏览器默认行为，例如页面滚动。这样，玩家进入交互区域之前，游戏就不会吞掉普通输入或干扰浏览器导航。

## 跟踪按住状态并处理按键释放

对于连续移动，在收到 keydown 时设置按键的保持状态，在收到 keyup 时清除。按键按住期间，浏览器可能重复触发 keydown；因此，跳跃等一次性动作应忽略重复事件，除非设计本身需要重复触发。游戏失去焦点或窗口失焦时，清除所有保持状态，因为焦点转移后 keyup 可能不会再送达游戏。

测试同时按下两个键、长按、快速点按，以及游戏失去焦点后重新获得焦点的情况。对于一次性动作，除非设计需要重复触发，否则应忽略重复的 keydown。MDN 介绍了 KeyboardEvent.key、KeyboardEvent.code 和事件类型；请选择与按键映射相符的属性。

## 常见问题

**游戏控制应该使用 KeyboardEvent.key 还是 KeyboardEvent.code？** 如果操作应由字符值或键盘布局决定，请用 KeyboardEvent.key。如果操作取决于按键的物理位置，请用 KeyboardEvent.code。明确说明采用哪种方式，并测试其他键盘布局。

**页面失去焦点时，为什么要清除保持按下的按键？** 焦点改变后，浏览器可能不会再向游戏发送释放事件 keyup。清除输入状态可以防止玩家返回时游戏仍认为按键处于按下状态。

## 跟随好奇心探索

- [管理浏览器游戏中的焦点](https://oneshotgems.ai/zh-Hans/topics/game-focus-management): 通过为游戏提供可见的焦点状态并在覆盖关闭后恢复焦点，使键盘输入、菜单和返回路径可预测。
- [跨设备测试浏览器游戏输入](https://oneshotgems.ai/zh-Hans/topics/testing-game-input-devices): 构建一个小型输入测试矩阵，涵盖真实的触摸、鼠标、键盘和方向行为，而不是依赖于一个桌面会话。
- [防止浏览器游戏中的按键卡住](https://oneshotgems.ai/zh-Hans/topics/preventing-stuck-game-keys): 当焦点或可见性发生变化时，安全地释放保持的移动，并测试可能导致游戏输入卡住的模糊、暂停和重新启动路径。

## 延伸阅读

- [MDN：键盘事件](https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent)

---
规范页面: https://oneshotgems.ai/zh-Hans/topics/keyboard-controls-for-games
