<canvas id="myCanvas" width="600" height="600"></canvas>
<script>
const canvas = document.getElementById("myCanvas");
const ctx = canvas.getContext("2d");
// Define a Ball class to represent the balls in the canvas
class Ball {
constructor(x, y, dx, dy, radius, color) {
this.x = x;
this.y = y;
this.dx = dx;
this.dy = dy;
this.radius = radius;
this.color = color;
}
// Define a draw() method to draw the ball on the canvas
draw() {
ctx.beginPath();
ctx.arc(this.x, this.y, this.radius, 0, Math.PI * 2);
ctx.fillStyle = this.color;
ctx.fill();
ctx.closePath();
}
// Define an update() method to update the position of the ball
update() {
this.x += this.dx;
this.y += this.dy;
// Reverse direction if the ball hits the canvas edge
if (this.x + this.radius > canvas.width || this.x - this.radius < 0) {
this.dx = -this.dx;
}
if (this.y + this.radius > canvas.height || this.y - this.radius < 0) {
this.dy = -this.dy;
}
}
// Define a collisionDetection() method to detect collisions between balls
collisionDetection(balls) {
for (let i = 0; i < balls.length; i++) {
if (this === balls[i]) continue;
if (getDistance(this.x, this.y, balls[i].x, balls[i].y) < this.radius + balls[i].radius) {
resolveCollision(this, balls[i]);
}
}
}
}
// Define a function to generate a random integer within a range
function getRandomInt(min, max) {
return Math.floor(Math.random() * (max - min + 1) + min);
}
// Define a function to get the distance between two points
function getDistance(x1, y1, x2, y2) {
const xDistance = x2 - x1;
const yDistance = y2 - y1;
return Math.sqrt(Math.pow(xDistance, 2) + Math.pow(yDistance, 2));
}
function resolveCollision(ball1, ball2) {
// Calculate the velocities and distances between the balls
const xVelocityDiff = ball1.dx - ball2.dx;
const yVelocityDiff = ball1.dy - ball2.dy;
const xDist = ball2.x - ball1.x;
const yDist = ball2.y - ball1.y;
// Check if the balls are moving towards each other
if (xVelocityDiff * xDist + yVelocityDiff * yDist >= 0) {
// Calculate the angle between the balls
const angle = -Math.atan2(yDist, xDist);
// Calculate the mass and velocity vectors for each ball
const m1 = ball1.radius;
const m2 = ball2.radius;
const u1 = rotate(ball1.dx, ball1.dy, angle);
const u2 = rotate(ball2.dx, ball2.dy, angle);
// Calculate the new velocity vectors for each ball
const v1 = { x: u1.x * (m1 - m2) / (m1 + m2) + u2.x * 2 * m2 / (m1 + m2), y: u1.y };
const v2 = { x: u2.x * (m1 - m2) / (m1 + m2) + u1.x * 2 * m1 / (m1 + m2), y: u2.y };
// Rotate the velocity vectors back to the original coordinate system
const vFinal1 = rotate(v1.x, v1.y, -angle);
const vFinal2 = rotate(v2.x, v2.y, -angle);
// Update the velocity vectors and positions of the balls
ball1.dx = vFinal1.x;
ball1.dy = vFinal1.y;
ball2.dx = vFinal2.x;
ball2.dy = vFinal2.y;
ball1.x += ball1.dx;
ball1.y += ball1.dy;
ball2.x += ball2.dx;
ball2.y += ball2.dy;
}
}
// Define a helper function to rotate a vector by an angle
function rotate(dx, dy, angle) {
const rotated = {
x: dx * Math.cos(angle) - dy * Math.sin(angle),
y: dx * Math.sin(angle) + dy * Math.cos(angle)
};
return rotated;
}
const balls = [];
// Create five balls with random properties
for (let i = 0; i < 5; i++) {
const x = getRandomInt(30, canvas.width-30);
const y = getRandomInt(30, canvas.height-30);
const dx = getRandomInt(-5, 5);
const dy = getRandomInt(-5, 5);
const radius = getRandomInt(10, 30);
const color = `rgb(${getRandomInt(0, 255)}, ${getRandomInt(0, 255)}, ${getRandomInt(0, 255)})`;
balls.push(new Ball(x, y, dx, dy, radius, color));
}
// Draw each ball on the canvas
//balls.forEach(ball => ball.draw());
function animate() {
// Clear the canvas
ctx.clearRect(0, 0, canvas.width, canvas.height);
// Update the position of each ball and redraw it on the canvas
balls.forEach(ball => {
ball.update();
ball.draw();
ball.collisionDetection(balls);
});
// Request the next animation frame
requestAnimationFrame(animate);
}
// Start the animation
animate();
</script>