3

我知道keypress即使在 上也有这个Window,如果你按住键,它会重复,但在重复开始之前它会有轻微的停顿。我不想要这种停顿。我正在编写一个游戏,我希望玩家立即做出反应,而不是在暂停之后。

处理基于网络的游戏的键盘事件的首选方法是什么?

4

2 回答 2

6

听“keydown”,而不是“keypress”。Keydown 会不断触发,直到您放手为止。

但:

不要只做类似的事情:

window.addEventListener("keydown", function (evt) {
    if (evt.keyCode === 32) { player.fire(); }
});

你最终会发现有些人每秒发射 15 次,有些人每秒发射 60 次,甚至有些人每秒发射 120 次。

相反,有一个 Keyboard 对象,它在 n 事件触发时随时更新:

var Keyboard = {
    keys : {},
    keyPress : function (evt) {
        if (this.keys[evt.keyCode] > 0) { return; }
        this.keys[evt.keyCode] = evt.timeStamp || (new Date()).getTime();
    },
    keyRelease : function (evt) {
        this.keys[evt.keyCode] = 0;
    }
};
window.addEventListener("keydown", Keyboard.keyPress.bind(Keyboard));
window.addEventListener("keyup", Keyboard.keyRelease.bind(Keyboard));

然后,在你的更新周期中,让角色检查Keyboard它想要的密钥。
作为额外的奖励,他们的键有一个第一次按下的时间戳,以防你想添加充电镜头,或者按住按钮跳得更高。

然后,您的单位应该在他们自己的更新区域内跟踪诸如允许他们多久开火的频率,以及最后一次是什么时候。

于 2012-11-25T16:30:44.587 回答
4

正如史蒂夫所说,这是不可能的。您应该监听 keydown / keyup 事件并跟踪按下了哪些按钮:

var pressedKeys = {};
$(window)
    .bind("keydown", function(e) {
        pressedKeys[e.keyCode] = true;
    })
    .bind("keyup", function(e) {
        delete pressedKeys[e.keyCode];
    })
;

我认为对于游戏来说,在某处处理所有这些事件的主循环很常见:

setInterval(function() {
    if (pressedKeys[38]) { // if up is pressed
        // do stuff
    }
}, 50);
于 2012-11-25T16:03:00.813 回答