-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathscript.js
More file actions
114 lines (96 loc) · 3.49 KB
/
Copy pathscript.js
File metadata and controls
114 lines (96 loc) · 3.49 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
const canvas = document.getElementById('canvas');
const ctx = canvas.getContext('2d');
// Set canvas size
canvas.width = 800;
canvas.height = 600;
// Ball class
class Ball {
constructor(x, y, radius, color) {
this.x = x;
this.y = y;
this.radius = radius;
this.color = color;
this.dx = (Math.random() - 0.5) * 8; // Random horizontal velocity
this.dy = (Math.random() - 0.5) * 8; // Random vertical velocity
this.mass = radius; // Mass proportional to radius
}
draw() {
ctx.beginPath();
ctx.arc(this.x, this.y, this.radius, 0, Math.PI * 2);
ctx.fillStyle = this.color;
ctx.fill();
ctx.closePath();
}
update(balls) {
// Bounce off walls
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;
}
// Check collision with other balls
balls.forEach(ball => {
if (ball === this) return; // Skip self
// Calculate distance between balls
const dx = ball.x - this.x;
const dy = ball.y - this.y;
const distance = Math.sqrt(dx * dx + dy * dy);
// Check if balls are colliding
if (distance < this.radius + ball.radius) {
// Collision resolution
const angle = Math.atan2(dy, dx);
const sin = Math.sin(angle);
const cos = Math.cos(angle);
// Rotate velocities
const vx1 = this.dx * cos + this.dy * sin;
const vy1 = this.dy * cos - this.dx * sin;
const vx2 = ball.dx * cos + ball.dy * sin;
const vy2 = ball.dy * cos - ball.dx * sin;
// Elastic collision formula
const finalVx1 = ((this.mass - ball.mass) * vx1 + 2 * ball.mass * vx2) / (this.mass + ball.mass);
const finalVx2 = ((ball.mass - this.mass) * vx2 + 2 * this.mass * vx1) / (this.mass + ball.mass);
// Rotate velocities back
this.dx = finalVx1 * cos - vy1 * sin;
this.dy = vy1 * cos + finalVx1 * sin;
ball.dx = finalVx2 * cos - vy2 * sin;
ball.dy = vy2 * cos + finalVx2 * sin;
// Move balls apart to prevent sticking
const overlap = (this.radius + ball.radius - distance) / 2;
const moveX = overlap * cos;
const moveY = overlap * sin;
this.x -= moveX;
this.y -= moveY;
ball.x += moveX;
ball.y += moveY;
}
});
// Update position
this.x += this.dx;
this.y += this.dy;
this.draw();
}
}
// Create balls
const balls = [
new Ball(400, 300, 20, 'red'),
new Ball(200, 200, 20, 'blue'),
new Ball(600, 400, 20, 'green'),
new Ball(300, 500, 20, 'orange'),
new Ball(500, 100, 20, 'white'),
// Adding 4 more green balls with different starting positions
new Ball(100, 100, 20, 'green'),
new Ball(700, 500, 20, 'green'),
new Ball(150, 450, 20, 'green'),
new Ball(650, 150, 20, 'green')
];
// Animation loop
function animate() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
balls.forEach(ball => {
ball.update(balls);
});
requestAnimationFrame(animate);
}
// Start animation
animate();