如何让点击多个球落下?

时间:2015-06-01 16:08:21

标签: javascript canvas javascript-events html5-canvas

我有一个从光标位置掉落的球,当光标移动到另一个位置时会发红光​​。我每次点击鼠标时都会尝试丢弃一个新球。我试过了:

canvas.addEventListener('click', function(event) {
  ball.draw();
});

但它似乎没有做任何事情。有没有办法在点击上画一个新球,而不是一遍又一遍地重绘同一个球?

以下是代码的其余部分:

var canvas = document.getElementById("canvas"),
    ctx = canvas.getContext("2d");
var W = window.innerWidth,
    H = window.innerHeight;
var running = false;

canvas.height = H; canvas.width = W;

var ball = {},
    gravity = .5,
    bounceFactor = .7;

ball = {
  x: W,
  y: H,
  radius: 15,
  color: "BLUE",
  vx: 0,
  vy: 1,

  draw: function() {
    ctx.beginPath();
    ctx.arc(this.x, this.y, this.radius, 0, Math.PI*2, false);
    ctx.fillStyle = this.color;
    ctx.fill();
    ctx.closePath();
  }
};

function clearCanvas() {
  ctx.clearRect(0, 0, W, H);
}

function update() {
  clearCanvas();
  ball.draw();

  ball.y += ball.vy;

  ball.vy += gravity;
  if(ball.y + ball.radius > H) {
    ball.y = H - ball.radius;
    ball.vy *= -bounceFactor;
  }
}

canvas.addEventListener("mousemove", function(e){
  ball.x = e.clientX;
  ball.y = e.clientY;
  ball.draw();
});
setInterval(update, 1000/60);

ball.draw();

1 个答案:

答案 0 :(得分:1)

只需重写球对象,使其变为实例化:

function Ball(W, H) {
  this.x = W;
  this.y = H;
  this.radius = 15;
  this.color = "blue";
  this.vx = 0;
  this.vy = 1;

}

将方法移动到原型(这将使它们可以跨实例共享)。此外,添加更新方法以便您可以本地化更新:

Ball.prototype = {
  draw: function() {
    ctx.beginPath();
    ctx.arc(this.x, this.y, this.radius, 0, Math.PI*2, false);
    ctx.fillStyle = this.color;
    ctx.fill();
    ctx.closePath();
  },

  update: function() {
    this.y += this.vy;
    this.vy += gravity;
    if(this.y + this.radius > H) {
      this.y = H - this.radius;
      this.vy *= -bounceFactor;
    }
  }
};

在点击事件中(考虑将数组重命名为复数形式 - 更容易区分这种方式。在您的代码中,您将覆盖"数组"(定义为一个对象)后面有一个球对象):

var balls = [];                // define an array to hold the balls

对于单击事件使用鼠标的x和y位置作为球的起点,我们首先需要调整它,因为它相对于客户端窗口而不是画布。为此,我们得到画布的绝对位置,并从客户端坐标中减去它:

canvas.addEventListener('click', function(event) {
  var rect = this.getBoundingClientRect(),  // adjust mouse position
      x = event.clientX - rect.left,
      y = event.clientY - rect.top;

  balls.push(new Ball(x, y));               // add a new instance
});

现在在主动画循环中迭代数组。每当有一个新球时,它将被考虑和更新 - 我们只是让循环运行直到满足某些条件(未显示):

function update() {
  clearCanvas();

  for(var i = 0, ball; ball = balls[i]; i++) {
    ball.draw();    // this will draw current ball
    ball.update();  // this will update its position
  }

  requestAnimationFrame();
}

实例

如果你将这些放在一起,你会得到:



var canvas = document.getElementById("canvas"),
    ctx = canvas.getContext("2d"),
    W = canvas.width, // simplified for demo
    H = canvas.height,
    gravity = .5,
    bounceFactor = .7;

function Ball(x, y) {
  this.x = x;
  this.y = y;
  this.radius = 15;
  this.color = "blue";
  this.vx = 0;
  this.vy = 1
}

Ball.prototype = {
  draw: function() {
    ctx.beginPath();
    ctx.arc(this.x, this.y, this.radius, 0, Math.PI * 2);
    ctx.fillStyle = this.color;
    ctx.fill();
    ctx.closePath();
  },

  update: function() {
    this.y += this.vy;
    this.vy += gravity;  // todo: limit bounce at some point or this value will be added
    if (this.y + this.radius > H) {
      this.y = H - this.radius;
      this.vy *= -bounceFactor;
    }
  }
};

function clearCanvas() {
  ctx.clearRect(0, 0, W, H);
}

var balls = []; // define an array to hold the balls

canvas.addEventListener('click', function(event) {
  var rect = this.getBoundingClientRect(),  // adjust mouse position
      x = event.clientX - rect.left,
      y = event.clientY - rect.top;
  balls.push(new Ball(x, y));               // add a new instance
});


(function update() {
  clearCanvas();

  for (var i = 0, ball; ball = balls[i]; i++) {
    ball.draw(); // this will draw current ball
    ball.update(); // this will update its position
  }

  requestAnimationFrame(update);
})();

canvas {background:#aaa}

<canvas id="canvas" width=600 height=400></canvas>
&#13;
&#13;
&#13;