用Canvas实现小球碰撞反弹的核心是位置更新、边界检测与速度反向;需定义小球对象属性,每帧更新坐标,触边时反转对应速度并校正位置,两球碰撞则通过圆心距判断并简化弹性响应。

用 Canvas 实现小球碰撞反弹,核心是模拟位置更新、边界检测和速度反向。不需要物理引擎,纯 JavaScript 就能做出真实感——关键是正确处理坐标、速度和碰撞响应。
1. 基础小球对象与运动逻辑
每个小球用对象表示,包含 x, y, vx, vy, radius, color 等属性。每帧用 requestAnimationFrame 更新位置:x += vx;y += vy;
这样小球就按当前速度匀速移动了。
2. 边界碰撞检测与反弹
画布四边是天然“墙壁”。检测小球是否触边,一旦超出,就反转对应方向的速度,并把位置拉回边界内(避免卡墙):
- 左边界:
if (x - r - 右边界:
if (x + r > canvas.width) { x = canvas.width - r; vx = Math.abs(vx); } - 上边界:
if (y - r - 下边界:
if (y + r > canvas.height) { y = canvas.height - r; vy = Math.abs(vy); }
注意:用 Math.abs 保证反弹后方向明确,避免因浮点误差导致速度趋近于零却未完全停止。
3. 小球间碰撞(弹性碰撞简化版)
两球碰撞需判断圆心距是否小于半径和:const dx = b2.x - b1.x;const dy = b2.y - b1.y;const distance = Math.sqrt(dx * dx + dy * dy);if (distance
立即学习“前端免费学习笔记(深入)”;
简化处理(忽略质量差异,假设等质量刚体):
- 计算碰撞法线方向单位向量:
nx = dx / distance;,ny = dy / distance; - 将两球速度分别投影到法线(n)和切线(t)方向
- 交换法线方向的速度分量(弹性碰撞核心),切向不变
- 重组新速度:
v1x = v1t * tx + v2n * nx;等
实际代码中可封装为 resolveCollision(ball1, ball2) 函数,每帧两两检测(O(n²),小球数少时足够高效)。
4. 加点真实感:重力与阻尼
让动画更自然,可在每帧加一个向下的重力加速度(如 vy += 0.2),再对速度乘以阻尼系数(如 vx *= 0.99; vy *= 0.99;)模拟空气阻力。地面反弹时还可让 vy 乘以 0.8 模拟能量损耗(恢复系数)。
不复杂但容易忽略细节:坐标系原点在左上角、浮点精度积累、碰撞后位置重叠需分离(否则下一帧重复触发)、多次碰撞顺序影响结果。先做单球碰墙,再加多球,最后调参——物理感就出来了。



















