运动与游戏开发
运动原理
如何实现运动
方法:
运动的物体使用绝对定位
通过改变定位物体的属性(left、right、top、bottom)值来使物体移动。例如向右或向左移动可以使用offsetLeft(offsetRight)来控制左右移动。
步骤:
开始运动前,先清除已有定时器,否则连续点击按钮会使物体运动速度越来越快。
开启定时器,计算速度
把运动和停止用if/else语句隔开,判断停止条件,执行运动
定时器
在javascritp中,有两个关于定时器的专用函数,它们是:
倒计定时器:timer=setTimeout(函数名,time);
循环定时器:timer=setInterval(函数名,time);
运动研究
运动:匀速运动(让物体动起来)
对定时器的使用
给DIV加绝对定位
offsetLeft
问题:到达某个特定位置停止
解决:做判断,符合条件时关闭定时器(存定时器timer)
速度变慢(一般不动时间,而是改数字 - 速度)
用变量存速度
问题:取7时,offsetLeft没有等于300的时候,div停不下来
解决:>=300 //停在 301
问题:到300后点击按钮还继续走
原因:点击按钮,执行函数,开定时器(执行当前函数一至少执行一次)
解决:加else (没有到达目标之前才执行)
问题:连续点击,速度变快
原因:每点击一次就开一个定时器,点击几次就有几个定时器同时工作
解决:保证每次只有一个定时器工作,先clearlnterval ()
逐渐变慢,最后停止
距离越远速度越大
速度有距离决定
速度=(目标值-当前值)/缩放系数
如果没有【缩放系数】速度太大,瞬间到达终点.没有过程
问题:并没有真正到达300
原因:速度只剩0.9
像素是屏幕能够显示的最小单位,并不会四舍五入掉 Math.ceil ()向上取整 Math.floor ()向下取整
问题:向左走,又差一块–Math.floor ()
判断:三目 speed=speed>0 ? Math.ceil ( speed ): Math.floor ( speed )
多物体运动
多个div ,鼠标移入变宽
运动框架传参obj,知道让哪个物体动起来
用到缓冲一定要取整
问题:div没运动回去 //清除前一个定时器
原因:只有一个定时器
解决:加物体上的定时器,使每个物体都有一个定时器。定时器作为物体属性
多个div淡入淡出
首先关闭物体上的定时器
经验:多物体运动框架所有东西都不能共用
问题:不是因为定时器,而是因为alpha
解决:作为属性附加到物体上 /不以变量形式存在
问题:offset 的 bug 加border变宽 原因:offsetWith并不是真正的width ,它获取的是盒模型尺寸
解决:躲着 宽度扔到行间,parselnt ( oDiv.style.width )
进一步解决: getStyle ( obj, name ) currentStyle , getComputedStyle 加border ,只要offset就有问题 去掉offset
链式运动
多出来的一个参数,只有传进去的时候才调用
鼠标移入变宽,结束之后弹出abc
先横向展开.再以向展开
鼠标移出,先变回不透明,变矮,变窄
var oDiv = document.getElementById('div1'); oDiv.onmouseenter = function(){ startMove(this,'width',300,function(){ startMove(this,'height',300,function(){ startMove(this,'opacity',100); }) }); };
5.封装运动框架
function startMove(node,attr,iTarget,complete){ clearInterval(node.timer); node.timer = setInterval(function(){ var iCur = null; //如果是透明度,我们需要转换到0-100的数计算 if (attr == 'opacity') { iCur = parseInt(parseFloat(getStyle(node,"opacity") * 100)); }else{ iCur = parseInt(getStyle(node,attr)); } //计算速度 var speed = (iTarget - iCur) / 8; speed = speed > 0 ? Math.ceil(speed) : Math.floor(speed); //运动和停止分开 if(iCur == iTarget){ clearInterval(node.timer); if (complete) { complete.call(node); } }else{ //如果是透明度则不能使用px并且需要除100得到原本的值 if (attr == 'opacity') { iCur += speed; node.style.opacity = iCur / 100; }else{ node.style[attr] = iCur + speed + 'px'; } } }, 30); }