使“球”在画布上跟随鼠标移动

5

我试图让一个球在画布区域内跟随鼠标移动。但是当鼠标进入画布区域时(即在边缘),球只会获得第一个位置。

为什么球在画布内移动时不跟随鼠标呢?请帮忙解决问题。

window.onload = startup;

var ballX = 400;
var ballY = 400;
var mouseX = 0;
var mouseY = 0;

function startup() {
  document.getElementById("drawingArea").onmouseover = mouseMove;
  setInterval("moveBall()", 100);
}

function mouseMove(evt) {
  mouseX = evt.clientX;
  mouseY = evt.clientY;
}

function moveBall() {
  if (ballX > mouseX) {
    ballX -= 5;
  } else {
    ballX += 5;
  }
  if (ballY > mouseY) {
    ballY -= 5;
  } else {
    ballY += 5;
  }

  var canvas = document.getElementById("drawingArea");
  var ctx = canvas.getContext("2d");

  ctx.clearRect(0, 0, canvas.width, canvas.height);

  ctx.beginPath();
  ctx.arc(ballX, ballY, 40, 0, 2* Math.PI);
  ctx.fillStyle = "green";
  ctx.fill();
  ctx.lineWidth = 5;
  ctx.strokeStyle = "red";
  ctx.stroke();
}
#drawingArea {
  border-style: solid;
  position: absolute;
  top: 0;
  left: 0;
}
<!doctype html>
<html>
  <head>
    <meta charset="UTF-8">
    <title>Move Ball</title>
  </head>

  <body>
    <canvas id="drawingArea" width="800" height="800" />
  </body>
</html>

3个回答

8
mouseover事件监听器不像“当鼠标悬停时,执行此代码”的形式。它只在状态变为true时触发,换句话说,当您将鼠标从外部移动到节点上时触发。

您想使用的正确事件是mousemove;存储鼠标的新位置,一旦它改变。

除此之外,我还对您的代码进行了一些其他更改,以使动画更加流畅:

这种ballX += mouseX>ballX? 5:-5的方法容易出现卡顿,因为它完全忽略了当鼠标和球在任何轴上相距少于5px时的区域。

同时,不要在游戏循环中使用setInterval()。更广义地说,不要使用带有字符串参数的setTimeout()setInterval()(完全不要使用)。这是一个不好的做法。不灵活,并强制您使用全局变量。

最好使用requestAnimationFrame(),这样您就可以与浏览器的呈现保持同步。

window.onload = startup;

var ballX = 400;
var ballY = 400;
var mouseX = 0;
var mouseY = 0;

function startup() {
  //`mousemove`, not `mouseover`
  document.getElementById("drawingArea").onmousemove = mouseMove;
  
  loop();
}

//use `requestAnimationFrame` for the game loop
//so you stay sync with the browsers rendering
//makes it a smoother animation
function loop(){
  moveBall();
  requestAnimationFrame(loop);
}

function mouseMove(evt) {
  mouseX = evt.clientX;
  mouseY = evt.clientY;
}

function moveBall() {
  //get the distance between the mouse and the ball on both axes
  //walk only the an eight of the distance to create a smooth fadeout
  var dx = (mouseX - ballX) * .125;
  var dy = (mouseY - ballY) * .125;
  //calculate the distance this would move ...
  var distance = Math.sqrt(dx*dx + dy*dy);
  //... and cap it at 5px
  if(distance > 5){
    dx *= 5/distance;
    dy *= 5/distance;
  }
  
  //now move
  ballX += dx;
  ballY += dy;
  
  var canvas = document.getElementById("drawingArea");
  var ctx = canvas.getContext("2d");

  ctx.clearRect(0, 0, canvas.width, canvas.height);

  ctx.beginPath();
  ctx.arc(ballX, ballY, 40, 0, 2 * Math.PI);
  ctx.fillStyle = "green";
  ctx.fill();
  ctx.lineWidth = 5;
  ctx.strokeStyle = "red";
  ctx.stroke();
}
#drawingArea {
  border-style: solid;
  position: absolute;
  top: 0;
  left: 0;
}
<canvas id="drawingArea" width="800" height="800" />

欢迎尝试一下运动代码。当你改变计算距离的* .125值或移除条件时,观察会发生什么...


2
您还需要添加onmousemove事件处理程序。

1
在这一行上:
document.getElementById("drawingArea").onmouseover = mouseMove;

...您需要将onmouseover更改为onmousemove。进一步阅读:onmousemove

更改后的完整示例:

   window.onload = startup;
   var ballX = 400;
   var ballY = 400;
   var mouseX = 0;
   var mouseY = 0;
   
   function startup() {
    document.getElementById("drawingArea").onmousemove = mouseMove;
    setInterval("moveBall()",100);
   
   }
   
   function mouseMove(evt) {
    mouseX = evt.clientX;
    mouseY = evt.clientY;
   }
   
   function moveBall() {
    if (ballX > mouseX) {
     ballX -= 5;
    } else {
     ballX += 5;
    }
    if (ballY > mouseY) {
     ballY -= 5;
    } else {
     ballY += 5;
    }
    
    var canvas = document.getElementById("drawingArea");
    var ctx = canvas.getContext("2d");
    
    ctx.clearRect(0, 0, canvas.width, canvas.height);
    
    ctx.beginPath();
    ctx.arc(ballX, ballY, 40, 0, 2* Math.PI);
    ctx.fillStyle = "green";
    ctx.fill();
    ctx.lineWidth = 5;
    ctx.strokeStyle = "red";
    ctx.stroke();
   }
#drawingArea 
{
    border-style: solid;
    position: absolute;
    top: 0;
    left: 0;
}
<!doctype html>
<html>
 <head>
  <meta charset="UTF-8">
  <title>Move Ball</title>
 </head>

 <body>
  <canvas id="drawingArea" width="800" height="800" />
 </body>
</html>


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接