Javascript "stuck"键(未注册的 keyup 事件)

标签 javascript keyboard coffeescript

使用 HTML5 Canvas 和 javascript 开发一个小游戏。而且它工作得很好,除了键盘键偶尔会“卡住”,即。它会注册一个 keydown 事件,但有时它不会注册 keyup 事件。这通常发生在一次按下多个键时,所以它部分是硬件或操作系统故障,但我希望有人知道如何解决这个问题。我的代码的相关部分(用 coffeescript 编写):

press = (direction) ->
    switch direction
        when 'W'
            game.keys.W = true
        when 'S'
            game.keys.S = true
        when 'A'
            game.keys.A = true
        when 'D'
            game.keys.D = true


release = (direction) ->
    switch direction
        when 'W'
            game.keys.W = false
        when 'S'
            game.keys.S = false
        when 'A'
            game.keys.A = false
        when 'D'
            game.keys.D = false

doKeyDown = (evt) ->
    switch evt.keyCode
        when 87 then press 'W'
        when 83 then press 'S'
        when 65 then press 'A'
        when 68 then press 'D'

doKeyUp = (evt) ->
    switch evt.keyCode
        when 87 then release 'W'
        when 83 then release 'S'
        when 65 then release 'A'
        when 68 then release 'D'

window.addEventListener('keydown', doKeyDown, false)

window.addEventListener('keyup', doKeyUp, false)

基本的东西。如果 javascript 不完全是事件驱动的,那不会有问题,但是你能做什么。我目前关于如何规避这个问题的想法是为按键添加一个队列,容量为 2 或 3 个键,当超过限制时,第一个键被删除并切换为“false” .尽管如此,在应该可以避免的情况下添加这样的人为限制似乎很奇怪!

因此,问题是,是否有一种直接的方法可以确保关键状态得到准确保存,而无需诉诸变通办法?最好是独立于游戏帧率的东西(无论它以 1000 fps 还是 3 fps 运行都应该同样有效)。

最佳答案

由于 keydown 事件会快速触发,您可以存储一个时间戳,记录您最后一次听到按键被按下的时间:

when 'A'
    game.keys.A = [true, +newDate()]

然后,运行一个间隔函数来检查仍然注册为按下但在一段时间内(比如 1 秒)没有发送 keydown 事件的键,并将它们设置为释放。

我上面的示例可能需要您重构大量代码(因为 game.keys.A 现在是数组而不是 bool 值)。相反,您可以将时间戳保存在它们自己的对象中:

last_keydown_times = {};
...

when 'A'
    game.keys.A = true
    last_keydown_times['A'] = +new Date();

让间隔函数检查 last_keydown_times 的成员(可能在 for...in 循环中)并检查过期值:

setInterval(function() {
    var now = +new Date();
    for(key in last_keydown_times) {
        if(now - last_keydown_times[key] >= 1000) {
            // run the release code for this key
        }
    }
}, 1000);

关于Javascript "stuck"键(未注册的 keyup 事件),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10949369/

相关文章:

javascript - 这个 javascript "translate"如何转换为 CoffeeScript?

javascript - 遍历 javascript 对象 - 第二部分

javascript - Ckeditor 自定义插件 - 带单选按钮的对话框

android - Eclipse Android 模拟器 - 键盘不工作

ios - 当 textView 显示键盘不起作用时向上移动 View

javascript - 我们可以使用键控函数的对象在运行时定义类吗?

javascript - Angular $routeParams 是空的

javascript - jQuery 重置切换状态?

javascript - jquery附加图像然后将它们放入轮播中

keyboard - 当键盘出现时,Flutter 小部件会调整大小。如何防止这种情况?