HTML Canvas Animation Bouncing Balls With Interactions
<!doctype html> <html lang="en"> <head> <meta charset="UTF-8"> </head>/*ww w .j a v a2s . c o m*/ <body> <canvas id="canvasOne" width="500" height="500"> Your browser does not support the HTML 5 Canvas. </canvas> <script type="text/javascript"> function drawScreen() { context.fillStyle = '#EEEEEE'; context.fillRect(0, 0, theCanvas.width, theCanvas.height); //Box context.strokeStyle = '#000000'; context.strokeRect(1, 1, theCanvas.width - 2, theCanvas.height - 2); update(); testWalls(); collide(); render(); } function update() { for (let i = 0; i < balls.length; i++) { ball = balls[i]; ball.nextx = (ball.x += ball.velocityx); ball.nexty = (ball.y += ball.velocityy); } } function testWalls() { let ball; let testBall; for (let i = 0; i < balls.length; i++) { ball = balls[i]; if (ball.nextx + ball.radius > theCanvas.width) { ball.velocityx = ball.velocityx * -1; ball.nextx = theCanvas.width - ball.radius; } else if (ball.nextx - ball.radius < 0) { ball.velocityx = ball.velocityx * -1; ball.nextx = ball.radius; } else if (ball.nexty + ball.radius > theCanvas.height) { ball.velocityy = ball.velocityy * -1; ball.nexty = theCanvas.height - ball.radius; } else if (ball.nexty - ball.radius < 0) { ball.velocityy = ball.velocityy * -1; ball.nexty = ball.radius; } } } function render() { let ball; context.fillStyle = "#000000"; for (let i = 0; i < balls.length; i++) { ball = balls[i]; ball.x = ball.nextx; ball.y = ball.nexty; context.beginPath(); context.arc(ball.x, ball.y, ball.radius, 0, Math.PI * 2, true); context.closePath(); context.fill(); } } function collide() { let ball; let testBall; for (let i = 0; i < balls.length; i++) { ball = balls[i]; for (let j = i + 1; j < balls.length; j++) { testBall = balls[j]; if (hitTestCircle(ball, testBall)) { collideBalls(ball, testBall); } } } } function hitTestCircle(ball1, ball2) { let retval = false; let dx = ball1.nextx - ball2.nextx; let dy = ball1.nexty - ball2.nexty; let distance = (dx * dx + dy * dy); if (distance <= (ball1.radius + ball2.radius) * (ball1.radius + ball2.radius)) { retval = true; } return retval; } function collideBalls(ball1, ball2) { let dx = ball1.nextx - ball2.nextx; let dy = ball1.nexty - ball2.nexty; let collisionAngle = Math.atan2(dy, dx); let speed1 = Math.sqrt(ball1.velocityx * ball1.velocityx + ball1.velocityy * ball1.velocityy); let speed2 = Math.sqrt(ball2.velocityx * ball2.velocityx + ball2.velocityy * ball2.velocityy); let direction1 = Math.atan2(ball1.velocityy, ball1.velocityx); let direction2 = Math.atan2(ball2.velocityy, ball2.velocityx); let velocityx_1 = speed1 * Math.cos(direction1 - collisionAngle); let velocityy_1 = speed1 * Math.sin(direction1 - collisionAngle); let velocityx_2 = speed2 * Math.cos(direction2 - collisionAngle); let velocityy_2 = speed2 * Math.sin(direction2 - collisionAngle); let final_velocityx_1 = ((ball1.mass - ball2.mass) * velocityx_1 + (ball2.mass + ball2.mass) * velocityx_2) / (ball1.mass + ball2.mass); let final_velocityx_2 = ((ball1.mass + ball1.mass) * velocityx_1 + (ball2.mass - ball1.mass) * velocityx_2) / (ball1.mass + ball2.mass); let final_velocityy_1 = velocityy_1; let final_velocityy_2 = velocityy_2; ball1.velocityx = Math.cos(collisionAngle) * final_velocityx_1 + Math.cos(collisionAngle + Math.PI / 2) * final_velocityy_1; ball1.velocityy = Math.sin(collisionAngle) * final_velocityx_1 + Math.sin(collisionAngle + Math.PI / 2) * final_velocityy_1; ball2.velocityx = Math.cos(collisionAngle) * final_velocityx_2 + Math.cos(collisionAngle + Math.PI / 2) * final_velocityy_2; ball2.velocityy = Math.sin(collisionAngle) * final_velocityx_2 + Math.sin(collisionAngle + Math.PI / 2) * final_velocityy_2; ball1.nextx = (ball1.nextx += ball1.velocityx); ball1.nexty = (ball1.nexty += ball1.velocityy); ball2.nextx = (ball2.nextx += ball2.velocityx); ball2.nexty = (ball2.nexty += ball2.velocityy); } let numBalls = 100; let maxSize = 15; let minSize = 5; let maxSpeed = maxSize + 5; let balls = new Array(); let tempBall; let tempX; let tempY; let tempSpeed; let tempAngle; let tempRadius; let tempRadians; let tempvelocityx; let tempvelocityy; theCanvas = document.getElementById('canvasOne'); context = theCanvas.getContext('2d'); for (let i = 0; i < numBalls; i++) { tempRadius = 5; let placeOK = false; while (!placeOK) { tempX = tempRadius * 3 + (Math.floor(Math.random() * theCanvas.width) - tempRadius * 3); tempY = tempRadius * 3 + (Math.floor(Math.random() * theCanvas.height) - tempRadius * 3); tempSpeed = 4; tempAngle = Math.floor(Math.random() * 360); tempRadians = tempAngle * Math.PI / 180; tempvelocityx = Math.cos(tempRadians) * tempSpeed; tempvelocityy = Math.sin(tempRadians) * tempSpeed; tempBall = { x : tempX, y : tempY, nextX : tempX, nextY : tempY, radius : tempRadius, speed : tempSpeed, angle : tempAngle, velocityx : tempvelocityx, velocityy : tempvelocityy, mass : tempRadius }; placeOK = canStartHere(tempBall); } balls.push(tempBall); } function canStartHere(ball) { let retval = true; for (let i = 0; i < balls.length; i++) { if (hitTestCircle(ball, balls[i])) { retval = false; } } return retval; } function gameLoop() { window.setTimeout(gameLoop, 20); drawScreen() } gameLoop(); </script> </body> </html>