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