Как сделать движение противника к персонажу?

// main functions
var canvas = document.querySelector('canvas');
var ctx = canvas.getContext('2d');
var inputState = { UP: false, LEFT: false, RIGHT: false, DOWN: false}
canvas.width =  1200;
canvas.height = 800;

player = {
  prevX:   0,
  prevY:   0,
  x:       canvas.width / 2,
  y:       canvas.height - 32,
  width:   16,
  height:  32,
  speed:   3,
};

obstacles = [{
  x:       600,
  y:       300,
  width:   100,
  height:  120,
  color:   '#00ff50'
}];

zombies = [{
  x:       900,
  y:       400,
  width:   16,
  height:  32,
  dx:      0,
  dy:      0
}]

// handle user input
var setKeyState = function(keyCode, isPressed) {
  switch (keyCode) {
    case 65: inputState.LEFT = isPressed; break;
    case 87: inputState.UP = isPressed; break;
    case 68: inputState.RIGHT = isPressed; break;
    case 83: inputState.DOWN = isPressed; break;
  }
};
var keydownHandler = (e) => {
  setKeyState(e.which, true);
};
var keyupHandler = (e) => {
  setKeyState(e.which, false);
};
document.addEventListener('keydown', keydownHandler);
document.addEventListener('keyup', keyupHandler);

var isCollided = function(obst, obj){
  if (obj.x + obj.width > obst.x
  && obj.x < obst.x + obst.width
  && obj.y < obst.y + obst.height
  && obj.y + obj.height > obst.y){
    return true;
  } else {
    return false;
  }
}

var collideHandler = function(obst, obj){
  if (isCollided(obst, obj)){
    if (obj.prevX >= obst.x + obst.width) {
      obj.x = obst.x + obst.width;
    }
    if (obj.prevX + obj.width <= obst.x) {
      obj.x = obst.x - obj.width;
    }
    if (obj.prevY + obj.height <= obst.y) {
      obj.y = obst.y - obj.height;
    }
    if (obj.prevY >= obst.y + obst.height){
      obj.y = obst.y + obst.height;
    }
  }
}

var moveZombie = function(zombie, player){
  if (zombie.x >= player.x + player.width) {
    zombie.dx = -1;
  }
  if (zombie.x + zombie.width <= player.x) {
    zombie.dx = 1;
  }
  zombie.dy = (player.y - zombie.y) * zombie.dx / (player.x - zombie.x);

  zombie.x += zombie.dx;
  zombie.y += zombie.dy;
}


var drawObj = function(obj, style){
  ctx.fillStyle = style;
  ctx.fillRect(obj.x, obj.y, obj.width, obj.height); 
}

var update = (step) => {
  player.prevX = player.x;
  player.prevY = player.y;

  if (inputState.LEFT) {
    player.x -= player.speed;
  }
  if (inputState.RIGHT) {
    player.x += player.speed;
  }
  if (inputState.UP) {
    player.y -= player.speed;
  }
  if (inputState.DOWN) {
    player.y += player.speed;
  }


  if (player.x >= canvas.width - player.width) {
    player.x = canvas.width - player.width;
  } else if (player.x <= 0) {
    player.x = 0;
  }
  if (player.y >= canvas.height - player.height) {
    player.y = canvas.height - player.height;
  } else if (player.y <= 0) {
    player.y = 0;
  }

  for (i in obstacles){
    collideHandler(obstacles[i], player);
  }

  for (i in zombies){
    moveZombie(zombies[i], player);
  }

};


var render = () => {
  ctx.fillStyle = 'lightGrey';
  ctx.fillRect(0, 0, canvas.width, canvas.height);


  //player
  drawObj(player, 'black');


  for (i in obstacles){
    drawObj(obstacles[i], obstacles[i].color);
  }

  for (i in zombies){
    drawObj(zombies[i], 'red');
  }
};



// game loop
var last = performance.now(),
    step = 1 / 60, // update should be called 60 times per second
    dt = 0,
    now;
var frame = () => {
  now = performance.now();
  dt = dt + (now - last) / 1000;
  while(dt > step) {
    dt = dt - step;
    update(step);
  }
  last = now;

  render(dt);
  requestAnimationFrame(frame);
}
requestAnimationFrame(frame);

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

Автор решения: Андрей Лобинцев

если кому нужно решил с помощью математики()

var moveZombie = function(zombie, player){
  let hyp = Math.sqrt((player.x - zombie.x)**2  + (player.y - zombie.y)**2);
  let catY0 = player.x - zombie.x;
  let catX0 = player.y - zombie.y;
  let sinFi = catX0 / hyp;
  let cosFi = catY0 / hyp;
  zombie.dx = zombie.speed * cosFi;
  zombie.dy = zombie.speed * sinFi;
  zombie.x += zombie.dx;
  zombie.y += zombie.dy;
}
→ Ссылка