第四周,做一个可以随便扔的重力球。
思路分析
1、首先我们得做一个小球,并且能使用鼠标控制(也就是拖拽功能)
2、小球在页面中反弹的效果我们可以用一个定时器不断的计算小球的 left 和 top 值来实现。
先实现拖拽功能
以正方形来了解一下拖拽的原理,希望自己能说清楚吧。
在屏幕上放下一个正方形
先给上代码,然后在细说
1、maxL
和 maxT
前面没有 var
是因为声明一个全局变量,后面还要用。
2、event
是一个事件对象。可以通过这个事件对象获得一些信息:导致事件的元素、事件的类型等。Chrome、FF等浏览器中可以直接获得这个对象,IE 中要用 window.event
获得,所以做一下兼容。
3、oEvent.offsetX
和 oEvent.offsetY
用来获取点击 box 时鼠标指针的位置距离 距离 box 左侧和顶部的距离。如下图:
4、得到上面的距离后,我们就可以间接计算出 box 左上角距离浏览器左上角的距离。即:
5、注意: event1
指的是 document
对象,event2
指的是 box
对象。所以不能这样写:
同样也不能使用 oBox.offsetLeft
直接得到 box 左上角距离浏览器左侧的距离,因为这是个定值,永远不会改变。
6、实际上我们得到的 left 和 top 画出了 box 左上角可变化的范围,如下图所示:
所以我们要判断当前 left 和 top 是否超出了这个范围:
7、最后把最后的 left 和 top 应用给 box:
8、鼠标松开后,将 onmousemove 事件移除
效果:
这就是拖拽,这么分析下来也是挺简单的。
9、还有一点,要把这个正方形变成一个小球,很简单:
接着昨天的往下讲。。。。(说好的一天一个小程序呢??)
下面来给小球加上 “重力” 。
何时开始有重力
前面说过,我们是通过定时器不断计算小球的 left 和 top 来实现这个反弹效果的。我们来思考一下什么时候触发这个定时器?当页面刷新后,小球在左上角,我们不点击它就不会有任何效果。当我们点击后,还是不应该触发,而是等拖拽动作完成,并且松开鼠标后触发。所以,我们应该这也做:
1、startMove()
是我们用来给小球添加“重力”的函数。结构就是这样。
“重力”
先给上代码吧,这样讲解比较方便
1、首先 var nowX = oBox.offsetLeft;var nowY = oBox.offsetTop;
获取 box 当前的坐标(被拖拽后)。
2、定时器为什么要选择 16 秒?因为肉眼可识别的帧率是60帧,所以每 16ms 改变一次小球的位置我们看起来就是连续的动画。
3、还记得拖拽中的那四个变量吗?分别是:lastX、lastY
记录上一次拖拽 box 的坐标; speedX、speedY
这次拖拽后 box 的坐标相对上次的变化量。
4、假如第一次 box 在 box1 处,拖拽后在 box2 处。则lastX = a;lastY = c;
speedX = b - a;speedY = d - c;
5、你可以把 speedX 、speedY 理解为鼠标拖动小球走的速度。因为执行一次循环的时间是一定的(16ms),这个值越大,说明鼠标移动的越快。同时也是每次执行定时器 box 的 left 或 top 的改变量。
6、值得注意的是:当没有触碰到边界时,nowX 和 nowY 的改变量是不会改变的。只有当触碰到边界时,这个值才会 *0.8 || *-0.8
。
7、那为什么小球 X 方向反弹一次就会慢慢停下来??
这是因为 Y 方向碰到边界也会使 speedX 衰减(注意看代码)。也就是说 横向的碰撞只影响 speedX,纵向的碰撞即改变横向也改变纵向。你可以这样做试一试:
小球 X 方向需要碰撞很多次才能停下来。
8、最后判断 speedX 和 speedY 的绝对值如果小于 1 。这个该变量完全可以忽略了没就让小球停下来。
基本的原理都讲完了,里面还有一些细节需要注意,比如说:何时清除定时器、作用域等问题。都是很基础的知识,就不说了。
终于讲完了,,里面也有许多不完美的地方,以后有时间在改吧!!
文章中如果有错误欢迎指出,非常乐意和大家一起交流。
完整代码可到 JavaScript-Programs 下载