备注:本文后面的代码,如果加载了ball.js,那么请使用这篇文章的ball.js代码.
边界反弹:
当小球碰到canvas的四个方向的时候,保持位置不变,把速度变成相反的方向
1 2 3 8 9 41 42 43 44 45
原理跟之前写的文章差不多,只是在碰到边界的时候,把速度调成反向的,小球就会反弹.
<head> <meta charset='utf-8' /> <style> #canvas { border: 1px dashed #aaa; } </style> <script> function Ball(x, y, r, color) { this.x = x || 0; this.y = y || 0; this.radius = r || 20; this.color = color || '#09f'; } Ball.prototype = { constructor: Ball, stroke: function (cxt) { cxt.strokeStyle = this.color; cxt.beginPath(); cxt.arc(this.x, this.y, this.radius, 0, 2 * Math.PI); cxt.closePath(); cxt.stroke(); }, fill: function (cxt) { cxt.fillStyle = this.color; cxt.beginPath(); cxt.arc(this.x, this.y, this.radius, 0, 2 * Math.PI); cxt.closePath(); cxt.fill(); } } </script> <script> window.onload = function () { var oCanvas = document.querySelector("#canvas"), oGc = oCanvas.getContext('2d'), width = oCanvas.width, height = oCanvas.height, ball = new Ball(width / 2, height / 2), vx = Math.random() * 2 + 5, vy = Math.random() * 2 + 5; ball.fill(oGc); (function move() { oGc.clearRect(0, 0, width, height); ball.x += vx; ball.y += vy; ball.fill(oGc); if (ball.x < ball.radius) { //碰到左边的边界 ball.x = ball.radius; vx = -vx; } else if (ball.y < ball.radius) { ball.y = ball.radius; vy = -vy; } else if (ball.x > width - ball.radius) { ball.x = width - ball.radius; vx = -vx; } else if (ball.y > height - ball.radius) { ball.y = height - ball.radius; vy = -vy; } requestAnimationFrame(move); })(); } </script> </head> <body> <canvas id="canvas" width="1200" height="600"></canvas> </body> run code
多个物体的反弹
1 2 3 8 9 51 52 53 54 55
原理是一样的,只是把坐标和速度的判断,基于一个个小球对象.
<head> <meta charset='utf-8' /> <style> #canvas { border: 1px dashed #aaa; } </style> <script> function Ball(x, y, r, color) { this.x = x || 0; this.y = y || 0; this.radius = r || 20; this.color = color || '#09f'; } Ball.prototype = { constructor: Ball, stroke: function (cxt) { cxt.strokeStyle = this.color; cxt.beginPath(); cxt.arc(this.x, this.y, this.radius, 0, 2 * Math.PI); cxt.closePath(); cxt.stroke(); }, fill: function (cxt) { cxt.fillStyle = this.color; cxt.beginPath(); cxt.arc(this.x, this.y, this.radius, 0, 2 * Math.PI); cxt.closePath(); cxt.fill(); } } </script> <script> window.onload = function () { var oCanvas = document.querySelector("#canvas"), oGc = oCanvas.getContext('2d'), width = oCanvas.width, height = oCanvas.height, balls = [], n = 50; function getRandColor() { return '#' + (function (color) { return (color += '0123456789abcdef'[Math.floor(Math.random() * 16)]) && (color.length == 6) ? color : arguments.callee(color); })(''); } for (var i = 0; i < n; i++) { var ball = new Ball(width / 2, height / 2, 20, getRandColor()); ball.vx = (Math.random() * 2 - 1) * 5; ball.vy = (Math.random() * 2 - 1) * 5; balls.push(ball); } (function move() { oGc.clearRect(0, 0, width, height); balls.forEach(function (ball) { ball.x += ball.vx; ball.y += ball.vy; ball.fill(oGc); if (ball.x < ball.radius) { //碰到左边的边界 ball.x = ball.radius; ball.vx = -ball.vx; } else if (ball.y < ball.radius) { ball.y = ball.radius; ball.vy = -ball.vy; } else if (ball.x > width - ball.radius) { ball.x = width - ball.radius; ball.vx = -ball.vx; } else if (ball.y > height - ball.radius) { ball.y = height - ball.radius; ball.vy = -ball.vy; } }); requestAnimationFrame(move); })(); } </script> </head> <body> <canvas id="canvas" width="1200" height="600"></canvas> </body> run code