我有一个从光标位置掉落的球,当光标移动到另一个位置时会发红光。我每次点击鼠标时都会尝试丢弃一个新球。我试过了:
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();
答案 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;