Змейка на js, остановка движении

Хочу написать змейку на js, но есть в когде косяк, при нажатии на другую кнопку комбинируются кнопки, смотрите сами, как решать эту проблему? пробовал сделать но не получилось (для движении нажмите на стрелки)

let elTop = 0;
let elLeft = 0;

function moveElement(evt) {
    let keypress = evt.keyCode;
    if (keypress == 38) {
        let x = setInterval(function(){ 
            document.querySelector(".player").style.top = (elTop = elTop - 15) + 'px';
        }, 100);
    }
    if (keypress == 40) {
        let y = setInterval(function(){ 
            document.querySelector(".player").style.top = (elTop = elTop + 15) + 'px';
        }, 100);
    }
    if (keypress == 37) {
        let z = setInterval(function(){ 
            document.querySelector(".player").style.left = (elLeft = elLeft - 15) + 'px';
        }, 100);
    }
    if (keypress == 39) {
        let w = setInterval(function(){ 
            document.querySelector(".player").style.left = (elLeft = elLeft + 15) + 'px';
        }, 100);
    }
}
document.addEventListener("keydown", moveElement);
.player{
    width: 20px;
    height: 20px;
    background-color: red;
    position: relative;
}
     <div class="player"></div>


Ответы (1 шт):

Автор решения: OPTIMUS PRIME

У вас после любого нажатия, многократно создаются setInterval, которые в дальнейшем нигде не останавливаются. Должен быть один цикл, меняющий координаты квадрата, а кнопки будут только переключать направление движения.

let snake = document.querySelector(".player");
let x = 0, y = 0;

let dx = 1, dy = 0;
// Одновременно только одна переменная принимает значение 1 или -1,
// Показывает направление движения.

let step = 20; // Сколько пикселей пройдет за "шаг" ( == Размер квадрата)

document.addEventListener("keydown", function(e) {
  switch (e.keyCode) {
    case 37: dx = -1, dy =  0; break; // left
    case 38: dx =  0, dy = -1; break; // top
    case 39: dx =  1, dy =  0; break; // right
    case 40: dx =  0, dy =  1; break; // bottom
  }
});


let tick = 200;

(function _loop() {
  x += dx * step;
  y += dy * step;
  // Надо уметь переключать значения x,y if (x <= 0) или if (x >= ширина_поля)

  snake.style.left = x + "px";
  snake.style.top = y + "px";

  // Функция через tick миллисекунд вызывается снова (и зацикливается)
  setTimeout(_loop, tick); // Меняя значение tick, можно менять скорость движения.
})();
.player {
  width: 20px;
  height: 20px;
  background-color: red;
  position: relative;
}
<div class="player"></div>

P.s. Попробуйте изначально рисовать змейку хотя бы из трех клеток. Чтобы не попасть в тупик, когда напишете весь код только для "головы", а потом окажется, что у змеи должно быть еще и тело xD

→ Ссылка