我有一个球,它从光标位置掉落,并在光标移动到另一个位置时重新掉落。我试图每次单击鼠标时都放一个新球。我试过了:
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();
最佳答案
只需重写ball对象,它就可以实例化:
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;
}
}
};
在click事件中(考虑将数组重命名为复数形式-更加容易区分。在代码中,稍后将用单个球形对象覆盖“数组”(定义为对象)):
var balls = []; // define an array to hold the balls
为了使click事件使用鼠标的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>