Interval to animate movement

I am attempting to make Snake in Vanilla JS to learn the features. Everything seems fine, but something is wrong with my setInterval() callback function. I want to animate it so that the snake actually moves in the last direction inputted, but it does this weird thing where it does the last two key presses again and again then disappears. This is my function, can anyone help?

document.addEventListener("keydown", function (event) {
    var direction;
    if (event.key === 'w') {
        direction = [-1, 0];
    }
    else if (event.key === 'a') {
        direction = [0, -1];
    }
    else if (event.key === 's') {
        direction = [1, 0];
    }
    else if (event.key === 'd') {
        direction = [0, 1];
    }
    try {
        var start = setInterval(function () {
            SNAKE_POS.push([SNAKE_POS[SNAKE_POS.length - 1][0] + direction[0], SNAKE_POS[SNAKE_POS.length - 1][1] + direction[1]]);
            SNAKE_POS.shift();
            populateRepBoard();
            renderBoard();
            
        }, 200);
    } catch (e) {
        alert("You Lose!");
        console.error(e);
    }

    
});

Answer

Your snake should have a velocity, and it should happen no matter whether there is any key press or not.

So you should have one “event happening” constantly: the setInterval() to keep your snake moving. That’s by Newton’s First Law: without any external force, your snake keeps on going the way it did.

Now, the key press: you “listen on” or observe on any keypress, as if it somehow can give external force to the snake so that it can move in another direction. That’s Newton’s Second Law: having some force on the object is able to have some acceleration on the object, which means a change of velocity. In really, the snake interact with the ground to get friction to move in another direction (the change of velocity). But you make it happen by listen on user’s key press.

So your program should be like this:

const intervalID = setInterval(() => {
  moveTheSnake();   // or use snake.move()
});

document.addEventListener("keydown", function (event) {
  // change the snake speed...
  // using if then else or case statements, you can use
  // changeSnakeVelocity([dx, dy]) or
  // snake.getVelocity([dx, dy])
  // where dx, dy per second is the snake's velocity
});