在一个keyup之后继续触发keydown事件



我正试图在3D游戏中实现移动,为了实现这一点,我必须处理多键检测。

所以我用这个

setControls(){
this.keyMap = {};
window.addEventListener('keydown', this.onMove.bind(this));
window.addEventListener('keyup', this.onMove.bind(this));
}
onMove(event){
this.keyMap[event.key] = event.type === "keydown";
//Move according to key pressed
}

keydown事件运行良好,当按下2个键时,我的对象同时在两个方向上移动。但当keyup事件被触发时,keyMap被设置为正确的值,但onMove只被调用一次,即使仍有一个键被按下,我的keyMap也不再更新。

我尝试了一些让我陷入无限循环的事情。

谢谢。

在创建带有输入的游戏时,不要将移动的逻辑置于按键本身。取而代之的是,有一个"主游戏循环",它将根据输入值是否在你的键映射中设置来移动对象。

将移动逻辑放置在输入中会导致输入延迟,因此在初始输入和后续输入之间会有一个停顿,使移动看起来和动作都很奇怪。通过将其添加到游戏逻辑而不是输入事件中,您将不会看到延迟。

这里有一个例子,它不使用画布或任何东西,但它演示了要点(使用WASD移动(:

const player = document.querySelector('.player')
const playerSpeed = 2
let x = 0, y = 0
const keyMap = {
a: false, d: false,
w: false, s: false
}
window.addEventListener('keydown', setKey)
window.addEventListener('keyup', setKey)
function setKey(event) {
keyMap[event.key] = event.type === 'keydown'
}
// Main Game loop
setInterval(() => {
// Calculate the internal x position
if (keyMap.a) { x -= playerSpeed }
if (keyMap.d) { x += playerSpeed }
// Calculate the internal y position
if (keyMap.w) { y -= playerSpeed }
if (keyMap.s) { y += playerSpeed }

// Set the new position of the player
// based on the internal x/y position
player.style.left = x + 'px'
player.style.top = y + 'px'
}, 10)
.player {
background: red;
position: absolute;
height: 50px;
width: 50px;
}
<div class="player"></div>

最新更新