跟踪按压作为状态,而不是重复的移动事件
在 keydown 时,将相关键添加到 Set 中;在更新步骤中,读取该集来决定移动。在 keyup 上,将其删除。这避免了将操作系统按键重复事件视为游戏的移动时钟。当动作只应开始一次时,例如发射一次蓄力射击,也忽略已按住的键的第二次按键。 MDN 描述了按住某个键会产生重复的 keydown 事件,而 KeyboardEvent.repeat 可以在支持的浏览器中识别这些重复事件。
选择哪些键算作游戏控制,并保留文本字段。如果提示或名称输入字段具有焦点,则移动处理程序不应使用相同的字符。仅针对真正需要该行为的控件阻止浏览器默认设置(例如页面滚动),并在玩家退出游戏区域时恢复正常的页面行为。
清除中断和状态变化的设置
当窗口模糊、文档隐藏、暂停覆盖控制或运行重置时,清除保留的输入。 visibilitychange 处理程序可以检查 document.hidden 并在其变为 true 时清除该集合。不要在每一帧或指针移动时盲目清除;将清除与键盘可能无法到达的中断联系起来。使游戏在恢复后需要重新按下按键,而不是自动恢复旧的移动。
再现中断路径
按住左方向键并切换选项卡,按住跳转并打开菜单,然后在重新启动时按方向键。返回游戏后,验证角色是否保持静止,直到再次有意按下。同时使用两个键重复操作,例如向右加跳跃,并确保清除一个键不会让另一个键保持锁定状态。包括游戏控件和文本输入之间的键盘焦点变化。
关于防止浏览器游戏中的按键卡住的常见问题
为什么释放按键后仍能保持按住状态?
当焦点改变或覆盖控制时,游戏可能无法接收或处理匹配的按键。重置这些中断路径上的保持状态可让玩家可以正常恢复游戏。
按键重复应该控制角色移动吗?
对于连续运动,跟踪保持状态并更新游戏循环中的运动。当操作应该发生一次时,重复对于区分重复的按键事件和初始按下事件更有用。
延伸阅读
发现信息过时了? 报告需要更正的内容