Как заставить программу правильно определять, где находится мышь по отношению к центральной точке окружности

#javascript #html5-canvas #dom-events #mouseevent #interaction

Вопрос:

Я создаю небольшую демо-версию/игру, в которой игрок перемещается и взаимодействует с объектами, нажимая на них.

 let cnt = 0;
var canvas = document.querySelector("canvas");
const ctx = canvas.getContext('2d');

canvas.width = window.innerWidth;
canvas.height = window.innerHeight;


canvas.style.background = "#91c1ff";

const player = {
  x: 1,
  y: 2
};
const xy = (x, y) => ({
  x,
  y
});
const dist = 25;

var speed = 5;

//grabs images for organelles
var ribosome = document.getElementById("ribosome");
var mito = document.getElementById("mito");


document.addEventListener('keydown', keyDownHandler, false);
document.addEventListener('keyup', keyUpHandler, false);

var rightPressed = false;
var leftPressed = false;
var upPressed = false;
var downPressed = false;




function keyDownHandler(event) {
  if (event.keyCode == 68) {
    rightPressed = true;
  }
  else if (event.keyCode == 65) {
    leftPressed = true;
  }
  if (event.keyCode == 83) {
    downPressed = true;
  }
  else if (event.keyCode == 87) {
    upPressed = true;
  }
  if (event.keyCode == 39) {
    rightPressed = true;
  }
  else if (event.keyCode == 37) {
    leftPressed = true;
  }
  if (event.keyCode == 40) {
    downPressed = true;
  }
  else if (event.keyCode == 38) {
    upPressed = true;
  }
}

function keyUpHandler(event) {
  if (event.keyCode == 68) {
    rightPressed = false;
  }
  else if (event.keyCode == 65) {
    leftPressed = false;
  }
  if (event.keyCode == 83) {
    downPressed = false;
  }
  else if (event.keyCode == 87) {
    upPressed = false;
  }
  if (event.keyCode == 39) {
    rightPressed = false;
  }
  else if (event.keyCode == 37) {
    leftPressed = false;
  }
  if (event.keyCode == 40) {
    downPressed = false;
  }
  else if (event.keyCode == 38) {
    upPressed = false;
  }
}





function draw() {
  ctx.setTransform(1, 0, 0, 1, 0, 0);
  ctx.clearRect(0, 0, canvas.width, canvas.height);

  const camX = -player.x   canvas.width / 2;
  const camY = -player.y   canvas.height / 2;
  ctx.translate(camX, camY);

  if (rightPressed) {
    player.x  = speed;
  }
  else if (leftPressed) {
    player.x -= speed;
  }
  if (downPressed) {
    player.y  = speed;
  }
  else if (upPressed) {
    player.y -= speed;
  }

  class Circle {
    constructor(xpoint, ypoint, radius, color) {
      this.xpoint = xpoint;
      this.ypoint = ypoint;
      this.radius = radius;
      this.color = color;
    }

    drawer(ctx){
      //ctx.drawImage(ribosome, this.xpoint, this.ypoint, 300, 300);
      //ctx.drawImage(mito, this.xpoint, this.ypoint, 300, 300);
      ctx.beginPath();
      ctx.arc(this.xpoint, this.ypoint, this.radius, 0, Math.PI * 2, false);
      ctx.fillStyle = this.color;
      ctx.fill();
      ctx.stroke();
      ctx.closePath();
    }

    clickCircle(xmouse, ymouse) {
      const distance = 
        Math.sqrt( 
      ((xmouse - this.xpoint ) * ( xmouse - this.xpoint))
          
        ((ymouse - this.ypoint) * (ymouse - this.ypoint))
        );
        console.log(distance);
    }

  }

  let circle = new Circle(200, 200, 100, "red");
  circle.drawer(ctx);

  canvas.addEventListener('click', (event) => {
    const rect = canvas.getBoundingClientRect();
    const x = event.clientX - rect.left;
    const y = event.clientY - rect.top;
    circle.clickCircle(x, y);

  });



  ctx.beginPath();
  ctx.arc(player.x, player.y, 10, 0, Math.PI * 2);
  ctx.stroke();

  requestAnimationFrame(draw)
}

draw(); 
 let cnt = 0;
var canvas = document.querySelector("canvas");
const ctx = canvas.getContext('2d');

canvas.width = window.innerWidth;
canvas.height = window.innerHeight;


canvas.style.background = "#91c1ff";

const player = {
  x: 1,
  y: 2
};
const xy = (x, y) => ({
  x,
  y
});
const dist = 25;

var speed = 5;

//grabs images for organelles
var ribosome = document.getElementById("ribosome");
var mito = document.getElementById("mito");


document.addEventListener('keydown', keyDownHandler, false);
document.addEventListener('keyup', keyUpHandler, false);

var rightPressed = false;
var leftPressed = false;
var upPressed = false;
var downPressed = false;




function keyDownHandler(event) {
  if (event.keyCode == 68) {
    rightPressed = true;
  }
  else if (event.keyCode == 65) {
    leftPressed = true;
  }
  if (event.keyCode == 83) {
    downPressed = true;
  }
  else if (event.keyCode == 87) {
    upPressed = true;
  }
  if (event.keyCode == 39) {
    rightPressed = true;
  }
  else if (event.keyCode == 37) {
    leftPressed = true;
  }
  if (event.keyCode == 40) {
    downPressed = true;
  }
  else if (event.keyCode == 38) {
    upPressed = true;
  }
}

function keyUpHandler(event) {
  if (event.keyCode == 68) {
    rightPressed = false;
  }
  else if (event.keyCode == 65) {
    leftPressed = false;
  }
  if (event.keyCode == 83) {
    downPressed = false;
  }
  else if (event.keyCode == 87) {
    upPressed = false;
  }
  if (event.keyCode == 39) {
    rightPressed = false;
  }
  else if (event.keyCode == 37) {
    leftPressed = false;
  }
  if (event.keyCode == 40) {
    downPressed = false;
  }
  else if (event.keyCode == 38) {
    upPressed = false;
  }
}





function draw() {
  ctx.setTransform(1, 0, 0, 1, 0, 0);
  ctx.clearRect(0, 0, canvas.width, canvas.height);

  const camX = -player.x   canvas.width / 2;
  const camY = -player.y   canvas.height / 2;
  ctx.translate(camX, camY);

  if (rightPressed) {
    player.x  = speed;
  }
  else if (leftPressed) {
    player.x -= speed;
  }
  if (downPressed) {
    player.y  = speed;
  }
  else if (upPressed) {
    player.y -= speed;
  }

  class Circle {
    constructor(xpoint, ypoint, radius, color) {
      this.xpoint = xpoint;
      this.ypoint = ypoint;
      this.radius = radius;
      this.color = color;
    }

    drawer(ctx){
      //ctx.drawImage(ribosome, this.xpoint, this.ypoint, 300, 300);
      //ctx.drawImage(mito, this.xpoint, this.ypoint, 300, 300);
      ctx.beginPath();
      ctx.arc(this.xpoint, this.ypoint, this.radius, 0, Math.PI * 2, false);
      ctx.fillStyle = this.color;
      ctx.fill();
      ctx.stroke();
      ctx.closePath();
    }

    clickCircle(xmouse, ymouse) {
      const distance = 
        Math.sqrt( 
      ((xmouse - this.xpoint ) * ( xmouse - this.xpoint))
          
        ((ymouse - this.ypoint) * (ymouse - this.ypoint))
        );
        console.log(distance);
    }

  }

  let circle = new Circle(200, 200, 100, "red");
  circle.drawer(ctx);

  canvas.addEventListener('click', (event) => {
    const rect = canvas.getBoundingClientRect();
    const x = event.clientX - rect.left;
    const y = event.clientY - rect.top;
    circle.clickCircle(x, y);

  });



  ctx.beginPath();
  ctx.arc(player.x, player.y, 10, 0, Math.PI * 2);
  ctx.stroke();

  requestAnimationFrame(draw)
}

draw(); 
 <!DOCTYPE html>
<html>

<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width">
    <title>Cellbot</title>
    <link href="style.css" rel="stylesheet" type="text/css" />
    <canvas id="canvas" width="100" height="100" style="border:1px solid #000000;"></canvas>
    <img src="images/ribosome.png" id="ribosome">
    <img src="images/mitochondrion.png" id="mito">
</head>

<body>
    <script src="script.js"></script>
</body>

</html> 

I want to use circles as the sort of «hitboxes» for the objects. However, when I tried to do this and test it with a console log using this tutorial it detects the mouse as being about 800-1000 pixels from where it’s supposed to be depending on the window size.

(It also registers a single click hundreds of times but that’s another issue)