首页 > 解决方案 > 在画布上添加多个球 onclick

问题描述

我正在尝试在 HTML5 画布中实现移动球动画。每当我单击画布时,我都想生成一个球。(位置和位移速度将是随机的)。

但问题是,每当我点击画布时,就会出现一个球,但前一个球的速度也会发生变化。我知道它正在发生,因为我再次运行相同的循环。

有人可以建议我对此的逻辑吗?

我试过下面的代码。

const canvas = document.getElementById('ballCanvas');
const ctx = canvas.getContext("2d");
let animBalls = [];
const animBallsColor = ['red','green','yellow']


ctx.fillStyle = "#FFF";
ctx.fillRect(0, 0, 1000, 800);

const Ball = function(bx,by,dx,dy,br = 10,color = "red",bv=0){

  this.bx = bx;
  this.by = by;
  this.bv = bv;
  this.br = br;
  this.dx = dx;
  this.dy = dy;
  this.color = color;
}

canvas.addEventListener('click', () => {
  animBalls.push(new Ball(
    Math.floor((Math.random() * 400) + 1),
    Math.floor((Math.random() * 500)),
    Math.floor((Math.random() * 5)),
    Math.floor((Math.random() * 3))
  ))
  console.log(animBalls)
  setInterval(run,10)

  if(animBalls.length > 10){
    canvas.removeEventListener('click', ()=>{
      console.log('quit')
    })
  }
})

function run(){
  ctx.clearRect(0,0,600,500);
  animBalls.forEach(function(ball){
    ctx.beginPath();
    ctx.fillStyle = ball.color;
    ctx.arc(ball.bx,ball.by,ball.br,0,Math.PI * 2,true);
    ctx.closePath();
    ctx.fill();

    ball.bx+=ball.dx;
    ball.by+=ball.dy;
   if(ball.bx<0 || ball.bx>canvas.width){
    ball.dx = -ball.dx
  }

   if(ball.by<0 || ball.by>canvas.height){
     ball.dy = -ball.dy;
   }
  })

标签: javascripthtmlhtml5-canvas

解决方案


问题出setInterval(run, 10)在点击处理程序内部。每次单击时,您都会开始一个新的间隔调用,每 10 毫秒运行一次

如果您只是将其从单击处理程序中取出并在您的工作正常后调用它:)

const canvas = document.getElementById('ballCanvas');
const ctx = canvas.getContext("2d");
let animBalls = [];
const animBallsColor = ['red','green','yellow']


ctx.fillStyle = "#FFF";
ctx.fillRect(0, 0, 1000, 800);

const Ball = function(bx,by,dx,dy,br = 10,color = "red",bv=0){

  this.bx = bx;
  this.by = by;
  this.bv = bv;
  this.br = br;
  this.dx = dx;
  this.dy = dy;
  this.color = color;
}

canvas.addEventListener('click', () => {
  animBalls.push(new Ball(
    Math.floor((Math.random() * 400) + 1),
    Math.floor((Math.random() * 500)),
    Math.floor((Math.random() * 5)),
    Math.floor((Math.random() * 3))
  ))
  console.log(animBalls)

  if(animBalls.length > 10){
    canvas.removeEventListener('click', ()=>{
      console.log('quit')
    })
  }
})

function run(){
  ctx.clearRect(0,0,600,500);
  animBalls.forEach(function(ball){
    ctx.beginPath();
    ctx.fillStyle = ball.color;
    ctx.arc(ball.bx,ball.by,ball.br,0,Math.PI * 2,true);
    ctx.closePath();
    ctx.fill();

    ball.bx+=ball.dx;
    ball.by+=ball.dy;
   if(ball.bx<0 || ball.bx>canvas.width){
    ball.dx = -ball.dx
  }

   if(ball.by<0 || ball.by>canvas.height){
     ball.dy = -ball.dy;
   }
  })
}

setInterval(run,10)

推荐阅读