Продолжать стрелять событие keydown после keyup - PullRequest
0 голосов
/ 28 марта 2020

Я пытаюсь реализовать движение в 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
    }

Клавиша событие работает нормально, мой объект движется в двух направлениях одновременно, когда нажаты 2 клавиши. Но когда вызывается событие keyup, для keyMap устанавливаются правильные значения, но onMove вызывается только один раз, и хотя еще нажата одна клавиша, моя keyMap больше не обновляется.

Я попробовал несколько вещей, которые меня поразили в бесконечность l oop.

Спасибо.

1 Ответ

2 голосов
/ 28 марта 2020

При создании игры с вводом не помещайте логику c движения в нажатие самой клавиши. Вместо этого используйте «Основную игру L oop», которая будет перемещать объект в зависимости от того, задано или нет значение ввода в вашей карте ключей.

Размещение логики движения c внутри ввода приводит к тому, что ввод задержитесь, поэтому между начальным входом и последующими входами будет пауза, заставляя движение выглядеть и вести себя странно. Добавив его в свою игровую логику c вместо события ввода, вы не увидите эту задержку.

Вот пример, в котором не используется холст или что-то еще, но он демонстрирует точку (используйте 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>
...