|
√ Google adsense申请技巧 √ 本站核心代理域名注册主机业务
√ 快速发布你的买卖域名买卖网站信息
√ 1元注册 cn域名
√ 站长每日新闻导读 √ ·推荐万网空间¥120元 150m √ 站长网:站长必上的网站 √ 网站联盟大全 √ 本站代理万网域名55空间120元 |
2.3 可以移动的方块
2.31 物理模型和面向对象
运行代码框
<div style="width:140px; height:140px; background-color:pink; cursor:pointer;" id="divBlock" ></div>
<script>
f=0.95; // 运动阻尼
k=0.85; // 碰撞弹性系数
g=1; // 重力加速度
window.onload=init;
function init(){
var obj;
obj=document.getElementById("divBlock");
obj.speedX=parseInt(Math.random()*5);
obj.speedY=parseInt(Math.random()*5);
obj.move=function(){
// 这里俺暂时不写,呵呵
}
}
</script>
2.311
这个模型很简单:
物体的属性:速度(包含 x 分量和 y 分量,这里设置为一个0-5的随机数)
物体的方法:运动
环境属性:运动阻尼 f, 和窗口边缘碰撞弹性系数 k, 重力加速度 g
2.312 注意 obj.move 那个方法(函数)的写法
2.32 让方块动起来
运行代码框
<div style="width:140px; height:140px; background-color:pink; cursor:pointer; position:absolute;" id="divBlock" ></div>
<script>
f=0.005; // 运动阻尼
k=0.7; // 碰撞弹性系数
g=1; // 重力加速度
var obj;
window.onload=init;
function init(){
obj=document.getElementById("divBlock");
obj.speedX=140;
obj.speedY=400;
obj.move=function(){
var x, y, mx, my;
x=this.offsetLeft;
y=this.offsetTop;
mx=document.body.clientWidth-this.offsetWidth; // 计算允许运动的最大范围
my=document.body.clientHeight-this.offsetHeight;
this.speedY+=g; // 计算重力加速度影响的y方向速度
this.speedX-=f*this.speedX*this.speedX*(this.speedX>0?1:-1); // 计算阻尼后的速度
this.speedY-=f*this.speedY*this.speedY*(this.speedY>0?1:-1); // 阻尼大小和速度平方成正比
if(Math.abs(this.speedX)>mx||Math.abs(this.speedY)>my){ this.speedX=this.speedX%mx; this.speedY=this.speedY%my; }
x+=this.speedX; y+=this.speedY; // 计算坐标
if(x<0){ x=-x; this.speedX=Math.abs(this.speedX)*k; } // 计算边界碰撞
if(y<0){ y=-y; this.speedY=Math.abs(this.speedY)*k; }
if(x>mx){ x=mx*2-x; this.speedX=-Math.abs(this.speedX)*k; }
if(y>my){ y=my*2-y; this.speedY=-Math.abs(this.speedY)*k; }
if(Math.abs(this.speedX)<1)this.speedX=0; // 消除数据下溢
if(Math.abs(my-y)<4&&Math.abs(this.speedY)<4){ y=my; this.speedY=0; } // 消除临界状态的抖动
this.style.left=parseInt(x)+"px"; // 实现移动
this.style.top=parseInt(y)+"px";
}
setInterval("obj.move();",10);
}
</script>
代码开始变难了啊,呵呵。请仔细阅读注释。
2.321 说到底只不过是个物理过程的算法表达而已。其中移动的实现和前面 2.22 节的拖动是类似的。
2.322 注意感觉这里代码中 this 的使用。我在 Obj.move 中使用 this 的时候,this指的就是 Obj
2.323 注意我把 Obj 放在了函数外面。这时候它就是一个全局变量。这是为了后面使用 setInterval 而准备的。很多菜鸟在用定时器的时候常常发现“找不到对象”的错误,请注意一下变量的定义域问题。
2.324 菜鸟注意学习内置对象 Math 的方法
2.33 让方块停下来
运行代码框
<div style="width:140px; height:140px; background-color:pink; cursor:pointer; position:absolute;" id="divBlock" ></div>
<script>
f=0.005; // 运动阻尼
k=0.7; // 碰撞弹性系数
g=1; // 重力加速度
var obj, timeHandle;
window.onload=init;
function init(){
obj=document.getElementById("divBlock");
obj.speedX=140;
obj.speedY=400;
obj.move=function(){
var x, y, mx, my;
x=this.offsetLeft;
y=this.offsetTop;
mx=document.body.clientWidth-this.offsetWidth; // 计算允许运动的最大范围
my=document.body.clientHeight-this.offsetHeight;
this.speedY+=g; // 计算重力加速度影响的y方向速度
this.speedX-=f*this.speedX*this.speedX*(this.speedX>0?1:-1); // 计算阻尼后的速度
this.speedY-=f*this.speedY*this.speedY*(this.speedY>0?1:-1); // 阻尼大小和速度平方成正比
if(Math.abs(this.speedX)>mx||Math.abs(this.speedY)>my){ this.speedX=this.speedX%mx; this.speedY=this.speedY%my; }
x+=this.speedX; y+=this.speedY; // 计算坐标
if(x<0){ x=-x; this.speedX=Math.abs(this.speedX)*k; } // 计算边界碰撞
if(y<0){ y=-y; this.speedY=Math.abs(this.speedY)*k; }
if(x>mx){ x=mx*2-x; this.speedX=-Math.abs(this.speedX)*k; }
if(y>my){ y=my*2-y; this.speedY=-Math.abs(this.speedY)*k; }
if(Math.abs(this.speedX)<1)this.speedX=0; // 消除数据下溢
if(Math.abs(my-y)<4&&Math.abs(this.speedY)<4){ y=my; this.speedY=0; } // 消除临界状态的抖动
this.style.left=parseInt(x)+"px"; // 实现移动
this.style.top=parseInt(y)+"px";
this.timeHandle=setTimeout("obj.move();",10);
}
obj.stop=function(){
clearTimeout(this.timeHandle);
}
obj.onmousedown=function(){ this.stop(); }
obj.onmouseup=function(){ this.move(); }
obj.move();
}
</script>
在方块上按下鼠标,它会停下来,弹起鼠标,它就继续跑了,呵呵。
2.331 没人注意到 2.211 绑定事件 - 回字的四种写法只举出了三种绑定事件的方法吗?呵呵,这里是第四种:
obj.onmousedown=function(){ this.stop(); }
2.332 我把 setInterval 改成了 setTimeout, 并且将定时器的句柄保存在了 obj 的属性里。这种使用定时器的做法是值得菜鸟借鉴的。
2.4 大结局 - 可以抛出的方块
运行代码框
<div style="width:140px; height:140px; background-color:pink; cursor:pointer; position:absolute;" id="divBlock" ></div>
<script>
f=0.003; // 运动阻尼
k=0.8; // 碰撞弹性系数
g=0.6; // 重力加速度
var obj, timeHandle;
window.onload=init;
function init(){
obj=document.getElementById("divBlock");
obj.speedX=0;
obj.speedY=0;
obj.lastX=obj.offsetLeft;
obj.lastY=obj.offsetTop;
obj.move=function(){
this.stop();
var x, y, mx, my;
x=this.offsetLeft;
y=this.offsetTop;
mx=document.body.clientWidth-this.offsetWidth; // 计算允许运动的最大范围
my=document.body.clientHeight-this.offsetHeight;
this.speedY+=g; // 计算重力加速度影响的y方向速度
this.speedX-=f*this.speedX*this.speedX*(this.speedX>0?1:-1); // 计算阻尼后的速度
this.speedY-=f*this.speedY*this.speedY*(this.speedY>0?1:-1); // 阻尼大小和速度平方成正比
if(Math.abs(this.speedX)>mx||Math.abs(this.speedY)>my){ this.speedX=this.speedX%mx; this.speedY=this.speedY%my; }
x+=this.speedX; y+=this.speedY; // 计算坐标
if(x<0){ x=-x; this.speedX=Math.abs(this.speedX)*k; } // 计算边界碰撞
if(y<0){ y=-y; this.speedY=Math.abs(this.speedY)*k; }
if(x>mx){ x=mx*2-x; this.speedX=-Math.abs(this.speedX)*k; }
if(y>my){ y=my*2-y; this.speedY=-Math.abs(this.speedY)*k; }
if(Math.abs(this.speedX)<1)this.speedX=0; // 消除数据下溢
if(Math.abs(my-y)<4&&Math.abs(this.speedY)<4){ y=my; this.speedY=0; } // 消除临界状态的抖动
this.style.left=parseInt(x)+"px"; // 实现移动
this.style.top=parseInt(y)+"px";
this.timeHandle=setTimeout("obj.move();",10);
}
obj.stop=function(){
clearTimeout(this.timeHandle);
}
obj.onmousedown=function(){ this.stop(); divBlock_event_mousedown(arguments[0]); }
obj.move();
}
function divBlock_event_mousedown(e){
var e, temp;
e=window.event?window.event:e;
obj.startX=e.clientX-obj.offsetLeft;
obj.startY=e.clientY-obj.offsetTop;
document.onmousemove=document_event_mousemove;
temp=document.attachEvent?document.attachEvent("onmouseup",document_event_mouseup):document.addEventListener("mouseup",document_event_mouseup,"");
}
function document_event_mousemove(e){
var e;
e=window.event?window.event:e;
with(obj.style){
position="absolute";
left=e.clientX-obj.startX+"px";
top=e.clientY-obj.startY+"px";
}
obj.speedX=(obj.offsetLeft-obj.lastX)*3;
obj.speedY=(obj.offsetTop-obj.lastY)*3;
obj.lastX=obj.offsetLeft;
obj.lastY=obj.offsetTop;
}
function document_event_mouseup(e){
var temp;
document.onmousemove="";
temp=document.detachEvent?document.detachEvent("onmouseup",document_event_mouseup):document.removeEventListener("mouseup",document_event_mouseup,"");
obj.move();
}
</script>
用鼠标按住方块,然后移动鼠标,同时松开鼠标,看看效果吧,呵呵
这个例子算结束了,哈哈。不作讲解了,各位自己看吧。