制作有趣的网页
canvas中模拟球的弹跳
我们如果让一个皮球从一定高度向地面落下,皮球就从静止逐渐加速,然后砸到地面并弹起,回到一定高度再次落向地面,如此反复,最终会停到地面上不动。这个过程从物理上是一个势能转变为动能的过程,而在地面的碰撞则遵循动量守恒。其实可以在浏览器的canvas中模拟这个过程。示例代码为:
为了表示势能转换为动能的过程,就要使用物理定律,一个简化版。
function drawBall(ctx,px,py,r){
ctx.beginPath();
ctx.arc(px, py, r, 0, Math.PI*2, true);
ctx.fill();
}
这主要是一个画圆的函数,用平面画圆表示一个球。函数中,要给出圆心坐标px和py,还有一个圆半径r。为了表示势能转换为动能的过程,就要使用物理定律,一个简化版。
const a=0.1,k=0.95;
其中设置了加速度为0.1,k则为地面的弹性系数,也就是表示球碰撞到地面会有多少弹性损失,k为1则没有弹性损失,会一直上下弹跳不停。当然也可以设置大于1,那么球会越弹越高,当然不符合现实情况。有了加速度a,就可以求出下一个时间点的速度:v+=a;
在碰到地面时,按照动量守恒,速度会反向,即:v=-v;
因为有能量损失,所以加上k值:v=-k*v;
这样一个简单的球落地弹起的动画就可以写为:(function drawFrame() {
window.requestAnimationFrame(drawFrame, canvas);
context.clearRect(0, 0, canvas.width, canvas.height);
drawBall(context,x,parseInt(y),r);
if(y>canvas.height-1-r){
v=-k*v;
}else{
v+=a;
}
y+=v;
}());
把上述代码加入html框架中,完整代码为:<!DOCTYPE html>
<html lang="zh-Hans">
<head>
<meta charset="gb18030" />
<title>球的弹跳</title>
<style type="text/css">
canvas{
border:1px solid #000;
}
</style>
</head>
<body>
<canvas id="canvas" width="400" height="600"> 你使用的浏览器不支持需要的功能,请升级或更换!</canvas>
<script type="text/javascript">
window.onload=function(){
const canvas = document.getElementById('canvas'),
context = canvas.getContext('2d'),
x=canvas.width/2,r=canvas.width/20,
a=0.1,k=0.95;
let y=r+10,v=0;
context.lineWidth=1;
context.fillStyle="#990000";
function drawBall(ctx,px,py,r){
ctx.beginPath();
ctx.arc(px, py, r, 0, Math.PI*2, true);
ctx.fill();
}
(function drawFrame() {
window.requestAnimationFrame(drawFrame, canvas);
context.clearRect(0, 0, canvas.width, canvas.height);
drawBall(context,x,parseInt(y),r);
if(y>canvas.height-1-r){
v=-k*v;
}else{
v+=a;
}
y+=v;
}());
};
</script>
</body>
</html>
将上述代码存为html文件,使用默认浏览器打开此文件,就可以看到一个球的下落及弹起的过程。现在一般模拟这样一种物理过程使用物理引擎库,比如最早出现的Box2D,是使用actionScript写的,这个物理引擎常用于游戏中,如著名的愤怒的小鸟就是使用它,后来有了js版本,但使用起来比较繁琐复杂,后来出现了matter.js,直接就是使用JavaScript编写的物理引擎库,可以用来模拟一些物理运动。现在还有了三维的物理引擎,可以实现3d动画的物理过程,如PhysicsJS等,不过还不是很成熟,还在发展中。