js小球的自由落体运动
1、/*css*/
*{margin: 0;padding: 0;}
#ball{
width:100px;height:100px;border-radius:100%;
background:radial-gradient(circle at 100px 100px,#dac9d2, #0e0000);
}
2、<!--html-->
<div id="ball" style="position: absolute;top:0px;left:0px"></div>
3、//js部分
var dball = document.getElementById('ball');
var width = document.documentElement.clientWidth || document.body.clientWidth; ////获得屏幕可用宽度,考虑碰撞
var height = document.documentElement.clientHeight || document.body.clientHeight; ////获得屏幕可用高度,考虑碰撞
var leftposition = parseInt(dball.style.left); ////获得小球左侧坐标(理解为小球的横向位置)
var topposition = parseInt(dball.style.top); ////获得小球上端坐标(理解为小球的纵向向位置)
var bool = true; //判断小球是否落到地面碰撞,速度增量得由正变为负了
var boolx = true; //X方向判断是否撞墙需反弹(反弹就是速度由正变为负)
var t00 = 0,
t01 = 0; //t00为小球下落期间,下落的上一个时刻,t01为下一个时刻
var t10 = 0,
t11 = 0; //t10为小球上升期间,上升的上一个时刻,t11为下一个时刻
var step = 0.1; //step为上一个时刻和下一个时刻的时间差
var speedy = 0; //小球下落阶段的位移增量(可以理解为下落时某一时间的速度值)
var speedy1 = 0; //小球上升阶段的位移增量(可以理解为上升时某一时间的速度值)
var speedym = 0; //用来保存小球与地面碰撞的瞬间时的位移增量(即小球下落时的最大速度)
var a = 1.2; //小球反弹后,交反弹前的速度损失比例(可以理解为能量损耗)
/////////////////////////水平方向的X位移,匀速运动,没啥看头//////////////////////////////////
function xmove() {
var speedx = 2;
leftposition =dball.offsetLeft;
if (leftposition + ball.offsetWidth >= width) {
leftposition=width- ball.offsetWidth-speedx;
//dball.style.left = leftposition + 'px';//使小球在浏览器窗口运动
boolx = true;
}
if (leftposition < 0) {
boolx = false
}
if (boolx) {
speedx = - 2;
} else speedx = 2;
dball.style.left = leftposition + speedx + 'px';
}
var doxmove = setInterval('xmove()', 5); /////线程未设清除,不关闭页面则一直会动下去
/////////////////////////////////////////////竖直方向的Y位移,核心部分////////////////////////////////////
function move()
{
if (bool) { ////////初始化为true,则下落
t01 = t00 + step; // 时间段1: 下一时刻相比于上一时刻
speedy = 5 * (t01 * t01 - t00 * t00); //由公式S=1/2gt1²-1/2gt0²转化而来,g设定为10;
t00 = t01; // 时间段1 的下一时刻 则是 时间段2的上一时刻 (有点绕,可以理解为T0~T1为一个时间段,T2~T3为相邻的下一个时间段,则T1==T2)
topposition = dball.offsetTop;
dball.style.top = topposition + speedy + 'px'; /////小球在某一时刻的位置变化
if (topposition + ball.offsetWidth + speedy >= height) {
speedym = speedy; //////保存最大位移增量,为下面反弹记录反弹时的初始位移增量(反弹的初始速度)
dball.style.top = topposition+'px'
t00 = 0;
t01 = 0; //此时,下落过程结束,必须初始化两个时刻(因为时刻不同,反应出的位移增量(速度)也不同)
bool = false; ///// 改变状态,得上升了
}
}
else {
t11 = t10 + step; //上升阶段和下落阶段的本质区别在于:下落阶段的初始速度为 0,上升阶段的初始速度为一个不为0的向上的值,其他的过程和状态都一致
speedy1 = 5 * (t11 * t11 - t10 * t10);
t10 = t11;
topposition = dball.offsetTop;
dball.style.top = topposition - (speedym / a) + speedy1 + 'px'; // (speedym/a)为上升阶段的初始位移增量(速度),a为能耗
if (speedy1 - (speedym / a) >= 0) { // 向下的位移增量(速度)和初始位移增量(速度)相等时,小球上升到最大高度,此时位移增量为0,改下落了
t10 = 0;
t11 = 0;
bool = true;
a = a + 0.1; //因为每撞击一次,小球第二次的下落速度会变小,因为速度越小,撞击时能量损耗越大,所以能量损耗比例越高
} //这也是模拟客观物体运动所需
}
}
var doymove = setInterval('move()', 10); //每10毫秒运行一次。没有关闭线程哦,但小球最终会在Y方向停下来,并不需要人为给它停止 。 (小球虽然停了,但线程依然在执行哦)