效果说明
本案例实现了一个具有重力和弹性效果的小球动画。小球会在画布中弹跳,并受到重力影响,模拟真实的物理运动。
核心实现
1. 物理模拟
小球的运动遵循简单的物理规律:
- 垂直方向受重力影响,速度会不断增加
- 水平方向保持匀速运动
- 位置根据速度更新
// 重力使垂直速度增加
ball.speedY += ball.gravity;
// 更新小球位置
ball.x += ball.speedX; // 水平位置 = 当前位置 + 水平速度
ball.y += ball.speedY; // 垂直位置 = 当前位置 + 垂直速度
2. 碰撞处理
当小球碰到边界时需要反弹:
- 碰到左右边界时,水平速度反向
- 碰到底部时,垂直速度反向
- 每次碰撞都会损失部分能量(由bounce系数控制)
// 水平碰撞(左右边界)
if (ball.x + ball.radius > canvas.width || ball.x - ball.radius < 0) {
// 速度反向,并损失部分能量
ball.speedX *= -ball.bounce; // bounce=0.8表示保留80%的速度
}
// 垂直碰撞(底部)
if (ball.y + ball.radius > canvas.height) {
// 1. 修正位置,防止小球陷入底部
ball.y = canvas.height - ball.radius;
// 2. 速度反向,并损失部分能量
ball.speedY *= -ball.bounce;
}
3. 拖尾效果
通过在每一帧绘制半透明背景来实现拖尾:
- 透明度越低,拖尾越长
- 透明度越高,拖尾越短
- 当前使用0.2的透明度,产生适中的拖尾长度
// 绘制半透明背景
ctx.fillStyle = 'rgba(26, 26, 26, 0.2)'; // 透明度0.2
ctx.fillRect(0, 0, canvas.width, canvas.height);
// 之前帧的小球会被半透明层遮住一部分
// 连续多帧后形成渐变消失的拖尾效果
关键参数说明
gravity: 重力加速度,控制下落速度bounce: 弹性系数(0-1),控制反弹力度- 1: 完全弹性碰撞,不损失能量
- 0: 完全非弹性碰撞,碰撞后停止
- 0.8: 保留80%的速度
speedX/speedY: 水平/垂直速度radius: 小球半径
扩展思路
- 添加多个小球
- 实现小球之间的碰撞
- 添加拖拽交互
- 自定义重力和弹性
- 添加空气阻力模拟