Bouncing Balls
Multiple balls bouncing in an enclosed space with ball-to-ball collisions.
What this code does
- Enclosed Room: 3D room with floor, walls, and ceiling for ball containment.
- Ball-to-Ball Collisions: realistic elastic collisions between multiple balls.
- Mass and Momentum: each ball has individual mass affecting collision response.
- Energy Conservation: physics simulation maintains realistic energy transfer.
- Friction Effects: air resistance and ground friction gradually slow movement.
- Interactive Controls: adjust gravity, bounciness, and ball count in real-time.
JavaScript (plain)
const scene = new THREE.Scene()
scene.background = new THREE.Color(0x87ceeb)
const camera = new THREE.PerspectiveCamera(75, width / height, 0.1, 1000)
camera.position.set(0, 5, 15)
const renderer = new THREE.WebGLRenderer({ antialias: true })
renderer.setSize(width, height)
renderer.shadowMap.enabled = true
document.querySelector('#app').appendChild(renderer.domElement)
let balls = []
let gravity = -0.015
let restitution = 0.85
let roomSize = 8
function createBall() {
const geometry = new THREE.SphereGeometry(0.5, 16, 16)
const material = new THREE.MeshStandardMaterial({
color: Math.random() * 0xffffff
})
const ball = new THREE.Mesh(geometry, material)
ball.position.set(
(Math.random() - 0.5) * roomSize,
Math.random() * 5 + 3,
(Math.random() - 0.5) * roomSize
)
ball.userData = {
velocity: new THREE.Vector3(
(Math.random() - 0.5) * 0.1,
0,
(Math.random() - 0.5) * 0.1
)
}
scene.add(ball)
balls.push(ball)
}
function animate() {
requestAnimationFrame(animate)
balls.forEach(ball => {
ball.userData.velocity.y += gravity
ball.position.add(ball.userData.velocity)
// Floor collision
if (ball.position.y - 0.5 < -roomSize/2) {
ball.position.y = -roomSize/2 + 0.5
ball.userData.velocity.y *= -restitution
}
// Wall collisions
if (Math.abs(ball.position.x) + 0.5 > roomSize/2) {
ball.position.x = Math.sign(ball.position.x) * (roomSize/2 - 0.5)
ball.userData.velocity.x *= -restitution
}
})
renderer.render(scene, camera)
}
animate()