1. 题目描述
再一个空间内存在一个球体按照一定的速度朝一个方向运动,当碰到空间边缘时,会反弹并继续运动。默认该空间中不存在任何摩擦阻力,再小球反弹过程中也不存在动能损耗(即小球一直再空间内做匀速运动)。
2. 题目分析
之前再完美世界的面试中遇到过这道题,小球的运动很好做,这道题的难点再触碰边界时的运动处理。当时把这道题想复杂了,完全再纠结反弹过程中的出入角计算。
其实我们都知道,一个物体再某个方向上的运动,可以被拆分为两个方向的运动(如平抛运动,可以拆分为水平方向的运动与垂直方向的运动)。
因此,只需要再小球碰壁时,改变其 x 轴或 y 轴的方向,就可以模拟出碰壁效果。
3. 代码实现
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
| <!DOCTYPE html> <html lang="en">
<head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head>
<body> <canvas id="myCanvas" style="border: 2px solid pink;"></canvas>
<script> const WIDTH = 1000 const HEIGHT = 500
const canvas = document.getElementById('myCanvas'); canvas.width = WIDTH; canvas.height = HEIGHT; const ctx = canvas.getContext('2d');
const speed = 10 const radius = 10 let currentX = 210 let currentY = 0 let xDir = 1 let yDir = 1
function animation() { canvas.width = canvas.width
ctx.beginPath(); ctx.arc(currentX, currentY, radius, 0, 2 * Math.PI); ctx.fill(); ctx.stroke()
currentX += speed * xDir currentY += speed * yDir
if (currentY <= 0) { yDir = 1 currentY = 0 } if (currentY >= HEIGHT) { yDir = -1 currentY = HEIGHT }
if (currentX <= 0) { xDir = 1 currentX = 0 } if (currentX >= WIDTH) { xDir = -1 currentX = WIDTH }
requestAnimationFrame(animation) }
animation() </script> </body>
</html>
|