在JavaScript中实现小球之间的碰撞检测和处理,通常涉及以下几个基础概念:
class Ball {
constructor(x, y, vx, vy, radius) {
this.x = x;
this.y = y;
this.vx = vx;
this.vy = vy;
this.radius = radius;
}
draw(ctx) {
ctx.beginPath();
ctx.arc(this.x, this.y, this.radius, 0, Math.PI * 2);
ctx.fillStyle = "#0095DD";
ctx.fill();
ctx.closePath();
}
update(canvas) {
this.x += this.vx;
this.y += this.vy;
// 边界碰撞检测
if (this.x + this.radius > canvas.width || this.x - this.radius < 0) {
this.vx = -this.vx;
}
if (this.y + this.radius > canvas.height || this.y - this.radius < 0) {
this.vy = -this.vy;
}
}
}
function collisionDetection(ball1, ball2) {
let dx = ball2.x - ball1.x;
let dy = ball2.y - ball1.y;
let distance = Math.sqrt(dx * dx + dy * dy);
return distance < ball1.radius + ball2.radius;
}
function handleCollision(ball1, ball2) {
let dx = ball2.x - ball1.x;
let dy = ball2.y - ball1.y;
let distance = Math.sqrt(dx * dx + dy * dy);
let overlap = 0.5 * (distance - ball1.radius - ball2.radius);
// 移动小球以避免重叠
let normX = dx / distance;
let normY = dy / distance;
ball1.x -= overlap * normX;
ball1.y -= overlap * normY;
ball2.x += overlap * normX;
ball2.y += overlap * normY;
// 碰撞响应
let vxTotal = ball1.vx - ball2.vx;
let vyTotal = ball1.vy - ball2.vy;
let vxRelative = dx / distance * vxTotal + dy / distance * vyTotal;
let vyRelative = dy / distance * vxTotal - dx / distance * vyTotal;
let impulse = 2 * vxRelative / (1 / ball1.mass + 1 / ball2.mass);
ball1.vx -= impulse * (1 / ball1.mass) * dx / distance;
ball1.vy -= impulse * (1 / ball1.mass) * dy / distance;
ball2.vx += impulse * (1 / ball2.mass) * dx / distance;
ball2.vy += impulse * (1 / ball2.mass) * dy / distance;
}
// 示例使用
const canvas = document.getElementById('canvas');
const ctx = canvas.getContext('2d');
const ball1 = new Ball(50, 50, 2, 1, 10);
const ball2 = new Ball(100, 100, -1, -2, 15);
function animate() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
ball1.update(canvas);
ball2.update(canvas);
ball1.draw(ctx);
ball2.draw(ctx);
if (collisionDetection(ball1, ball2)) {
handleCollision(ball1, ball2);
}
requestAnimationFrame(animate);
}
animate();
通过这种方式,可以实现小球之间的碰撞检测和响应,从而创建出更加真实和动态的效果。
领取专属 10元无门槛券
手把手带您无忧上云