Simple move by arrow keys

by OPTlMUS

HTML

<div id="container">
  <div id="zombie"></div>
</div>

CSS

#container {
  position: relative;
  width: 300px;
  height: 300px;
  border: 1px solid red;
}

#zombie {
  position: absolute;
  width: 40px;
  height: 40px;
  
  background-color: #462;
  border-radius: 50%;
  box-shadow: inset 0 4px 2px #c00;
}

#zombie::before,
#zombie::after  {
  content: "";
  position: absolute;
  top: 35%;
  width: 40%;
  height: 40%;
  border-radius: 50%;
  background-color: #ddd;
}
#zombie::before {
  left: 10%;
}
#zombie::after {
  right: 10%;
}

JavaScript

let d = { x: 0, y: 0 };
// Описывают направление движения.
// Оба принимают значения 1 или -1;

let moving = false;

document.addEventListener("keydown", function(e) {
  if (!/arrow(up|down|left|right)/i.test(e.key)) return;
  
  switch (e.key) {
    case "ArrowUp"   : d.y = -1; break;
    case "ArrowRight": d.x =  1; break;
    case "ArrowDown" : d.y =  1; break;
    case "ArrowLeft" : d.x = -1; break;
  }
    
  if (!moving) move();
});

document.addEventListener("keyup", function(e) {
  switch (e.key) {
    case "ArrowUp"   : d.y = 0; break;
    case "ArrowRight": d.x = 0; break;
    case "ArrowDown" : d.y = 0; break;
    case "ArrowLeft" : d.x = 0; break;
  }
});

/***/
let zombie = document.querySelector("#zombie");
let speed = 4;

const X_LIMIT = 300 - 40; /* Размер блока - размер зомби */
const Y_LIMIT = 300 - 40; /* см. getComputedStyle() */

function move() {
  if (d.x == 0 && d.y == 0) {
    // Незачем продолжать перерисовку и жрать ресурсы,
    // если ничего не меняется.
    moving = false;
    return;
  }
  
  moving = true;
  
  let new_y = parseFloat(zombie.style.top || 0) + d.y * speed;
  let new_x = parseFloat(zombie.style.left || 0) + d.x * speed;
  
  zombie.style.top = Math.max(0, Math.min(Y_LIMIT, new_y)) + "px";
  zombie.style.left = Math.max(0, Math.min(X_LIMIT, new_x)) + "px";
  
  requestAnimationFrame(move);
}