Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/469.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
删除javascript中的按键延迟_Javascript_Events_Javascript Events - Fatal编程技术网

删除javascript中的按键延迟

删除javascript中的按键延迟,javascript,events,javascript-events,Javascript,Events,Javascript Events,我有以下问题: 我正在尝试编写一个javascript游戏,角色由箭头键控制。 问题是,当一个人保持按键时,第一次按键和重复按键之间会有一个短暂的延迟。 此外,当按下“向右箭头键”并保持按下状态,然后按下“向上箭头键”时,角色不会移动到右上角,而是停止向正确方向移动并开始向上移动。 这是我正在使用的代码: <body onLoad="Load()" onKeyDown="Pressed(event)"> 函数按下(e){ cxc=e.keyCode; 如果(cxc==37) 移

我有以下问题: 我正在尝试编写一个javascript游戏,角色由箭头键控制。
问题是,当一个人保持按键时,第一次按键和重复按键之间会有一个短暂的延迟。
此外,当按下“向右箭头键”并保持按下状态,然后按下“向上箭头键”时,角色不会移动到右上角,而是停止向正确方向移动并开始向上移动。
这是我正在使用的代码:

<body onLoad="Load()" onKeyDown="Pressed(event)">

函数按下(e){ cxc=e.keyCode; 如果(cxc==37) 移动(-1,0); 如果(cxc==38) 移动(0,-1); 如果(cxc==39) Move(1,0); 如果(cxc==40) 移动(0,1); }
有人有想法吗?

由于此事件是将
任何东西从一个位置移动到一个位置,为什么不使用
onkeypress
事件,因此,如果用户键按
向上
键,那么
任何东西都将继续向上移动,就像按
键一样(e)
将被多次调用,直到用户释放密钥

<body onLoad="Load()" onkeypress="Pressed(event)">

如果您希望以可控方式重复按键,则必须自己实现,因为按键事件的触发取决于操作系统对按键重复方式的理解。这意味着可能存在可变的初始和后续延迟,同时按住两个键只会导致其中一个重复

您必须记录每个键当前是否按下,并在键已按下时忽略
keydown
事件。这是因为当自动重放发生时,许多浏览器会触发一个
keydown
keypress
事件,如果您自己重放key repeat,则需要抑制该事件

例如:

// Keyboard input with customisable repeat (set to 0 for no key repeat)
//
function KeyboardController(keys, repeat) {
    // Lookup of key codes to timer ID, or null for no repeat
    //
    var timers= {};

    // When key is pressed and we don't already think it's pressed, call the
    // key action callback and set a timer to generate another one after a delay
    //
    document.onkeydown= function(event) {
        var key= (event || window.event).keyCode;
        if (!(key in keys))
            return true;
        if (!(key in timers)) {
            timers[key]= null;
            keys[key]();
            if (repeat!==0)
                timers[key]= setInterval(keys[key], repeat);
        }
        return false;
    };

    // Cancel timeout and mark key as released on keyup
    //
    document.onkeyup= function(event) {
        var key= (event || window.event).keyCode;
        if (key in timers) {
            if (timers[key]!==null)
                clearInterval(timers[key]);
            delete timers[key];
        }
    };

    // When window is unfocused we may not get key events. To prevent this
    // causing a key to 'get stuck down', cancel all held keys
    //
    window.onblur= function() {
        for (key in timers)
            if (timers[key]!==null)
                clearInterval(timers[key]);
        timers= {};
    };
};
然后:


尽管如此,大多数基于动作的游戏都有固定时间的主帧循环,您可以将上/下键处理绑定到主帧循环中。

您可以在下键时开始移动,但只能在上键时结束。

我这样解决了这个问题:

var pressedl = 0; var pressedu = 0; var pressedr = 0; var pressedd = 0; function Down(e) { cxc = e.keyCode; if(cxc == 37) pressedl = 1; if(cxc == 38) pressedu = 1; if(cxc == 39) pressedr = 1; if(cxc == 40) pressedd = 1; //alert(cxc); } function Up(e) { cxc = e.keyCode; if(cxc == 37) pressedl = 0; if(cxc == 38) pressedu = 0; if(cxc == 39) pressedr = 0; if(cxc == 40) pressedd = 0; //alert(cxc); } var-pressedl=0; var-pressedu=0; var-pressedr=0; var-pressedd=0; 函数向下(e){ cxc=e.keyCode; 如果(cxc==37) 按L=1; 如果(cxc==38) 按u=1; 如果(cxc==39) 按EDR=1; 如果(cxc==40) 按EDD=1; //警报(cxc); } 功能启动(e){ cxc=e.keyCode; 如果(cxc==37) 按L=0; 如果(cxc==38) 按u=0; 如果(cxc==39) 按EDR=0; 如果(cxc==40) 按EDD=0; //警报(cxc); }

这是Lucas更抽象的解决方案:


似乎你一次只能按3个键,这让我很惊讶。

我在这方面完全是新手,但为什么不将KeyDown和keydup结合起来呢?我现在正在做一个类似的项目,在检查完之后,我将着手研究如何将这两个事件结合起来,以便在上下两个事件之间的整个时间内实现所需的效果。

这与@bobince的优秀答案几乎相同

我稍微修改了它,以允许间隔的单个值

// Keyboard input with customisable repeat (set to 0 for no key repeat)
// usage
/**
KeyboardController({
    32: {interval:0, callback: startGame },
    37: {interval:10, callback: function() { padSpeed -= 5; } },
    39: {interval:10, callback: function() { padSpeed += 5; } }
});
*/

function KeyboardController(keyset) {
    // Lookup of key codes to timer ID, or null for no repeat
    //
    var timers= {};

    // When key is pressed and we don't already think it's pressed, call the
    // key action callback and set a timer to generate another one after a delay
    //
    document.onkeydown= function(event) {
        var key= (event || window.event).keyCode;
        if (!(key in keyset))
            return true;
        if (!(key in timers)) {
            timers[key]= null;
            keyset[key].callback();
            if (keyset[key].interval !== 0)
                timers[key]= setInterval(keyset[key].callback, keyset[key].interval);
        }
        return false;
    };

    // Cancel timeout and mark key as released on keyup
    //
    document.onkeyup= function(event) {
        var key= (event || window.event).keyCode;
        if (key in timers) {
            if (timers[key]!==null)
                clearInterval(timers[key]);
            delete timers[key];
        }
    };

    // When window is unfocused we may not get key events. To prevent this
    // causing a key to 'get stuck down', cancel all held keys
    //
    window.onblur= function() {
        for (key in timers)
            if (timers[key]!==null)
                clearInterval(timers[key]);
        timers= {};
    };
};
我还计划使用setTimeout而不是setInterval,原因如下:


修改和测试后,我将更新此答案。

您的代码肯定无法工作。我不确定你是否能在JS中测试同时按下两个键。我将等待答案。好吧,它确实有效,但并不像预期的那样。我的游戏是基于计时器的游戏,通过等待重复的击键来缩短1秒是不好的。这太令人沮丧了。没有闪光灯,这太多的工作,而且对每个人都不起作用。我的游戏将是“非flash游戏”。我更喜欢HTML5?这也不适用于所有人!事实上Flash有98%的采用率。是的,但HTML5将适用于所有人……同样的问题。1秒的延迟仍然存在,当按下两个键时,它只能识别其中的1个。如果解决方案如此简单,那就太麻烦了。只需使用公认答案中的代码^^^^^^^^^虽然效果很好,但很容易集成:)这太棒了! var pressedl = 0; var pressedu = 0; var pressedr = 0; var pressedd = 0; function Down(e) { cxc = e.keyCode; if(cxc == 37) pressedl = 1; if(cxc == 38) pressedu = 1; if(cxc == 39) pressedr = 1; if(cxc == 40) pressedd = 1; //alert(cxc); } function Up(e) { cxc = e.keyCode; if(cxc == 37) pressedl = 0; if(cxc == 38) pressedu = 0; if(cxc == 39) pressedr = 0; if(cxc == 40) pressedd = 0; //alert(cxc); }
// Keyboard input with customisable repeat (set to 0 for no key repeat)
// usage
/**
KeyboardController({
    32: {interval:0, callback: startGame },
    37: {interval:10, callback: function() { padSpeed -= 5; } },
    39: {interval:10, callback: function() { padSpeed += 5; } }
});
*/

function KeyboardController(keyset) {
    // Lookup of key codes to timer ID, or null for no repeat
    //
    var timers= {};

    // When key is pressed and we don't already think it's pressed, call the
    // key action callback and set a timer to generate another one after a delay
    //
    document.onkeydown= function(event) {
        var key= (event || window.event).keyCode;
        if (!(key in keyset))
            return true;
        if (!(key in timers)) {
            timers[key]= null;
            keyset[key].callback();
            if (keyset[key].interval !== 0)
                timers[key]= setInterval(keyset[key].callback, keyset[key].interval);
        }
        return false;
    };

    // Cancel timeout and mark key as released on keyup
    //
    document.onkeyup= function(event) {
        var key= (event || window.event).keyCode;
        if (key in timers) {
            if (timers[key]!==null)
                clearInterval(timers[key]);
            delete timers[key];
        }
    };

    // When window is unfocused we may not get key events. To prevent this
    // causing a key to 'get stuck down', cancel all held keys
    //
    window.onblur= function() {
        for (key in timers)
            if (timers[key]!==null)
                clearInterval(timers[key]);
        timers= {};
    };
};