javascript 删除javascript中的按键延迟
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3691461/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
remove key press delay in javascript
提问by alex
I have the following problem:
I'm trying to write a javascript game, and the character is being controlled by the arrow keys.
The problem is, when one keeps the key pressed, there is a short delay between firing the first keypress and the repeated kepress.
Also, when one presses the "right arrow key" and keeps it pressed, and then presses the "up arrow key" the character doesn't move to the top right corner, but stops the moving in the right direction and starts moving up.
This is the code I'm using:
我有以下问题:我正在尝试编写一个 javascript 游戏,并且角色由箭头键控制。
问题是,当一个人按住按键时,在触发第一次按键和重复按键之间会有短暂的延迟。
此外,当按下“向右箭头键”并保持按下时,然后按下“向上箭头键”时,字符不会移动到右上角,而是停止向右移动并开始向上移动。
这是我正在使用的代码:
<body onLoad="Load()" onKeyDown="Pressed(event)">
function Pressed(e) {
cxc = e.keyCode;
if(cxc == 37)
Move(-1,0);
if(cxc == 38)
Move(0,-1);
if(cxc == 39)
Move(1,0);
if(cxc == 40)
Move(0,1);
}
does anybody have an idea??
有人有想法吗??
回答by bobince
If you want key repeat in a controllable fashion, you will have to implement it yourself, as keypress events are fired dependent on the OS's idea of how keys should repeat. That means there may be variable initial and following delays, and holding down two keys at once will cause only one of them to repeat.
如果您希望以可控方式重复按键,则必须自己实现,因为按键事件的触发取决于操作系统对按键应如何重复的想法。这意味着可能会有可变的初始和后续延迟,同时按住两个键只会导致其中一个重复。
You will have to keep a record of whether each key is currently pressed, and ignore keydownevents when the key is already down. This is because many browsers will fire a keydownas well as a keypressevent when an autorepeat occurs, and if you're reproducing key repeat yourself you'll need to suppress that.
您必须记录每个键当前是否被按下,并keydown在键已按下时忽略事件。这是因为当自动重复发生时,许多浏览器会触发一个keydown和一个keypress事件,如果你自己复制关键重复,你需要抑制它。
For example:
例如:
// 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= {};
};
};
then:
然后:
// Arrow key movement. Repeat key five times a second
//
KeyboardController({
37: function() { Move(-1, 0); },
38: function() { Move(0, -1); },
39: function() { Move(1, 0); },
40: function() { Move(0, 1); }
}, 200);
Although, most action-based games have a fixed-time main frame loop, which you can tie the key up/down handling into.
尽管如此,大多数基于动作的游戏都有一个固定时间的主帧循环,您可以将键向上/向下处理绑定到其中。
回答by alex
I've solved it like this:
我是这样解决的:
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);
}
<body onLoad="Load()" onKeyDown="Down(event)" onKeyUp="Up(event)">
<body onLoad="Load()" onKeyDown="Down(event)" onKeyUp="Up(event)">
回答by supakeen
You could start the movement onkeydown and only end it onkeyup?
你可以开始 onkeydown 运动,然后只结束它 onkeyup?
回答by chim
This is nearly the same as the excellent answer from @bobince
这与@bobince 的优秀答案几乎相同
I've amended it slightly to allow individual values for the interval
我稍微修改了它以允许间隔的单个值
// 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= {};
};
};
I've also got a plan to use setTimeout instead of setInterval for the reasons given in this question: setTimeout or setInterval?
由于这个问题中给出的原因,我还计划使用 setTimeout 而不是 setInterval:setTimeout 还是 setInterval?
I'll update this answer once I've amended and tested.
一旦我修改和测试,我会更新这个答案。
回答by dirkk0
This here is Lucas' solution in a more abstract version:
这是 Lucas 的更抽象版本的解决方案:
Seems you can only press 3 keys at a time to my surprise.
令我惊讶的是,您一次只能按 3 个键。
回答by jtmengel
I'm a total novice at this, but why not combine KeyDown with KeyUp? I am working on a similar project right now and, after checking out quirksmodeI am going to set forth at figuring out how to combine the two events such that the whole time between a Down and Up realizes the desired affect.
我在这方面完全是新手,但为什么不将 KeyDown 与 KeyUp 结合起来呢?我现在正在做一个类似的项目,在检查了quirksmode之后,我将着手弄清楚如何组合这两个事件,以便在 Down 和 Up 之间的整个时间实现所需的效果。
回答by Garis M Suero
As this event is to move whateverfrom one position to one position, why don't you use onkeypressevent, so in that way if the user key pressed the upkey, the whateverwill keep moving up, as the Pressed(e)will be called many times until the user releases the key.
由于这个事件是whatever从一个位置移动到一个位置,你为什么不使用onkeypress事件,这样如果用户按键按下该up键,whatever它将继续向上移动,因为Pressed(e)将被多次调用直到用户释放钥匙。
<body onLoad="Load()" onkeypress="Pressed(event)">

