Dreamweaver FrontPage HTML/CSS Javascript 
Google adsense申请技巧本站核心代理域名注册主机业务 快速发布你的买卖域名买卖网站信息 1元注册 cn域名
站长每日新闻导读 √ ·推荐万网空间¥120元 150m 站长网:站长必上的网站网站联盟大全本站代理万网域名55空间120元
 2007-1-15 14:16:57

网页制作前台之javascript

来源: 字体:[ ]


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>

 

用鼠标按住方块,然后移动鼠标,同时松开鼠标,看看效果吧,呵呵

这个例子算结束了,哈哈。不作讲解了,各位自己看吧。

 

 

网站地图 - 域名注册续费虚拟主机代理 - 交易论坛 - 网站投稿 - 广告服务 - 帮助中心 - 联系我们
Copyright ©2003-2007 www.Admin5.com All Rights Reserved