轻轻松松学习JavaScript


Posted in Javascript onFebruary 25, 2007

JavaScript 的历史虽短,但却发展迅速。最初NetScape开发了LiveScript语言,使得它的Navigator和Web 服务器产品有了基本的脚本编写功能。当 Navigator 2.0中加入了Java小程序后,NetScape才把LiveScript变成了JavaScript,至此JavaScript诞生。  

本文将以一个有趣的小程序为开端,介绍JavaScript的基本语法与功能。此趣味程序为小球碰撞仿真程序,它可仿真弹性碰撞和动能有损的不完全恢复碰撞。你若想了解此例程中的球间碰撞处理程序,需熟悉矢量的坐标旋转和一些基本的物理学知识。如果你对此一窍不通,也没什么关系,因为对于小球之间的碰撞程序仅为几个函数,你只管调用就是了,这并不影响我们对JavaScript 的学习。之所以要写这样一个带点旁门左道的趣味例程,只是希望你对JavaScript多增加一分兴趣。  

废话就不多说,现在开始吧。  

第一步:材料的准备  

制作两张小球图片,红球 、蓝球 各一张。图片格式为 GIF。你可先用3D软件制作出立体球图片,然后再将其转为GIF格式,这样程序动画会显得更加逼真。需注意的是图片背景一定要透明,不然就会让人看出破绽。最后还需一张背景图,图片格式同上。  

第二步:编写主页骨架  

1. 在NetObject ScriptBuilder 中用New 命令生成一个HTML文件的骨架。顺便在新生成的HTML文件中,将TITLE标志之间的文字改为"小球碰撞仿真演示程序"。  

2. 加入背景图案和小球图片资源。  
将BODY标志改为,此语句中的background 属性指定window.gif 为背景图案。  

为加载小球图片资源,在标志与间添加以下两句  

 

这两句HTML脚本的含义完全相同,标志IMG用于加入图片资源,其中SRC属性指明加入的图片文件名。ID属性指出图片的对象名称,这是个重要属性,因为以后在JavaScript 编程中要使用它。如第一句中,指明BallBlue为图片资源的对象名称(你可以把它想象成变量名)。STYLE属性指明图片在浏览器中的风格,其中"position" 开关设为"absolute",这样图片在窗口中的定位就可使用绝对坐标模式,而非文本行模式。  

HTML 部分的编写到此完成。接下来该用JavaScript 让图片动起来了。  

第三步:编写JavaScript 程序  

1.仿真程序使用窗口对象的SetTimeout()方法循环调用Move_Step()函数,达到移动图片的目的,而Move_Step()根据速度矢量来计算移动一步的长度和方向。碰撞处理分为两部分,第一是球对墙壁的碰撞处理,其处理函数为Ball_Crash_Wall(),第二是球体之间的碰撞处理,其处理函数为Ball_Crash_Ball()。还需设置一些碰撞标志变量,记录当前碰撞状态,以避免仿真误差带来的错误,也许现在你还不明白为什么误差会导致错误,不要紧,后面会慢慢告诉你。  

2.图片对象使用属性 style.pixelLeft、style.pixelTop 指定图片在窗口上的位  
置,这两个属性是图片运动的关键。不过在计算图片移动位置时并不用它,而是用数组变量BallCoord 记录图片当前坐标位置,因为属性 style.pixelLeft、style.pixelTop 是整型变量,而在计算碰撞中有小数生成,这样如果直接用 style.pixelLeft、style.pixelTop 记录位置,除了有误差,最重要的是在窗口边缘发生某些类型的球间碰撞时,会产生小球被撞出屏幕的错误。而数组变量可为浮点型,用于存放小数,从而避免了错误的发生。  

(一)变量定义与程序的初始化  

JavaScript 语句可放在HTML文件的主体(BODY区)中或文件头(HEAD区)中,区别是HEAD 区一般摆放预制好的函数和全局变量,以供BODY区的语句调用,而BODY区一般放入程序初始语句。JavsScript 的变量定义比较自由,但仍需满足先定义后使用的基本规则。  

1.在HEAD区中定义全局变量:  
Window_Top = 22 //窗口顶端位置。  
Window_Left = 22 //窗口左端位置。  
Window_Bottom = 294 //窗口底端位置。  
Window_Right = 590 //窗口右端位置。  
Setp_Proportion = 3.00 //速度放大比率。  

BallCoord = new Array(new Array(2),new Array(2)) //定义一个二维数组,用于记录两球的当前坐标。  

BallDiametre = new Array(66,92) //定义一维数组,存放两球的直径,其值分别为66和92。  

BallMoveVector = new Array(new Array(2,1),new Array(1,-2))//定义一个二维数组,用于记录两球的速度向量,第二维分别存放X与Y轴的速度。  

CrashingWall = new Array(new Array(false,false,false,false),new Array(false,false,false,false))//数组 CrashingWall 用于避免墙壁碰撞的二次计算,值为 true ,表明当前处于碰撞状态。初值为 false。  

2.在BODY区中完成程序的初始工作。其内容如下:  

这里你已经看见了一个JavaScript 程序的框架。标志SCRIPT 告诉浏览器,下面的内容为脚本程序,用LANGUAGE="JavaScript" 指明程序语言为JavaScript。不管是在BODY区,还是HEAD区中,任何JavaScript程序必须放在 标志之间。程序中用 new Array() 定义了一个数组Balls,以便以后存放图片对象。接下来的语句Balls[0] = BallBlue 将图片对象BallBlue 赋给Balls[0],如果你细心,你会发现BallBlue正是加载图片资源语句中指定的对象名。语句Balls[0].style.pixelTop = BallCoord[0][0] = 100,同时将值100赋给数组变量BallCoord[0][0]和图片对象的style.pixelTop属性。从而坐标数组变量BallCoord[0][0]得到了初值并且指定了球1的初始顶端位置。其余语句的含义雷同。最后一句调用函数Move_Step()将小球移动一步。  

(二) 单步移动函数Move_Step()讲解  

在HTML文件的HEAD区中编写Move_Step() 函数其内容如下:  
function Move_Step() {  
Ball_Crash_Ball() //调用球间碰状处理函数  

Balls_Crash_Wall(0) //调用蓝球碰墙处理函数  
Balls_Crash_Wall(1) //调用红球碰墙处理函数  

//计算移动步长  
BallCoord[0][0] += BallMoveVector[0][0] * Setp_Proportion  
BallCoord[0][1] += BallMoveVector[0][1] * Setp_Proportion  
BallCoord[1][0] += BallMoveVector[1][0] * Setp_Proportion  
BallCoord[1][1] += BallMoveVector[1][1] * Setp_Proportion  
//移动一步  
Balls[0].style.pixelTop = BallCoord[0][0]  
Balls[0].style.pixelLeft = BallCoord[0][1]  
Balls[1].style.pixelTop = BallCoord[1][0]  
Balls[1].style.pixelLeft = BallCoord[1][1]  
window.setTimeout("Move_Step()",100) //100毫秒后再次调用Move_Step()函数  
}  
该函数的大部分含义,你可看其中的注释,这里只对几点加以说明。  

1在语句BallCoord[0][0] += BallMoveVector[0][0] * Setp_Proportion中, BallMoveVector数组存放着速度向量。Setp_Proportion 变量存放步长放大比率,BallMoveVector[0][0] 乘以Setp_Proportion 得到移动一步的长度。最后该语句加上BallCoord[0][0]原值后再赋给BallCoord[0][0]本身,得到移动位置。  

2.语句window.setTimeout("Move_Step()",100) 表示100毫秒后再次调用Move_Step()函数。现在有了setTimeout()方法,程序就不断的循环起来了。  

Ball_Crash_Ball()是小球之间的碰撞处理函数, 你只管调用就是了,如果你不使用它,程序一样能运行,只是少了处理球间碰撞的功能。(在Ball_Crash_Ball()函数中调用了函数CrashEnd_Speed() 与atan360(x,y),以及使用了全局变量CrashingBalls,因而要正确使用它,必须将以上所说的函数与变量都拷入你的程序中)  

(三) 在HEAD区中编写墙壁碰撞处理函数Balls_Crash_Wall()  

一个简化的函数如下:  

function Balls_Crash_Wall(i) {  

if( BallCoord[i][0] <= Window_Top)  
BallMoveVector[i][0] = - BallMoveVector[i][0]  

if ( BallCoord[i][1] <= Window_Left)  
BallMoveVector[i][1] = - BallMoveVector[i][1]  

if ( BallCoord[i][0] + BallDiametre[i] >= Window_Bottom)  
BallMoveVector[i][0] = - BallMoveVector[i][0]  

if ( BallCoord[i][1] + BallDiametre[i] >= Window_Right)  
BallMoveVector[i][1] = - BallMoveVector[i][1]  

}  

函数首先判断是否球已经碰到了墙壁,如是就将相应方向上的速度方向反向,而大小不变。但这个函数有可能发生错误(错误发生的原因有些复杂,这里只梢作提示。由于小球移动的步长往往大于1个点,而仿真又是离散进行的,从而在有些情况下会发生错误)。需用数组变量CrashingWall 来标识碰撞状态,使得小球与墙壁处于碰撞状态时不能再发生第二次小球与墙壁的碰撞,相应的语句也要更改,如第一句改为  

if( BallCoord[i][0] <= Window_Top)  
{ if (!CrashingWall[i][0]) { BallMoveVector[i][0] = - BallMoveVector[i][0] }  
CrashingWall[i][0] = true  
} else CrashingWall[i][0] = false  

语句中CrahingWall数组的类型为逻辑型,记录球与墙壁是否正在发生碰撞。当为碰撞状态时,就不必再将球的运动方向反向。  

到此程序的编写基本完成,其它详细内容见光盘的原程序及说明。现在在NetObject ScriptBuilder 中选择菜单Preview 项,运行程序。  

附注:  
1. 运行本例程需先安装IE4.0以上浏览器 或Netscape Navigator 4.0以上浏览器  

2. 球间碰撞处理提示:当两球发生碰撞时,计算两球圆心连线与X轴的夹角。在依据此夹角对坐标进行旋转。将原速度矢量映射到旋转后的坐标中。从而将球间的任意碰撞转变为正对心碰撞。用冲量定理可推出碰后的速度计算公式。然后再将坐标旋转成原始坐标。可得碰撞后的速度矢量。看了上面的文字是不是有些烦人,其实并非如此,程序中只用了11行语句就完成了全部计算。

Javascript 相关文章推荐
javascript函数库-集合框架
Apr 27 Javascript
js数组操作常用方法
May 08 Javascript
jquery mobile页面跳转后样式丢失js失效的解决方法
Sep 06 Javascript
从数据库读取数据后将其输出成html标签的三种方法
Oct 13 Javascript
javascript基本包装类型介绍
Apr 10 Javascript
jQuery实现滚动切换的tab选项卡效果代码
Aug 26 Javascript
JavaScript中的this使用详解
Jul 27 Javascript
jQuery 控制文本框自动缩小字体填充
Jun 16 jQuery
Echarts之悬浮框中的数据排序问题
Nov 08 Javascript
JavaScript实现的滚动公告特效【基于jQuery】
Jul 10 jQuery
基于vue和bootstrap实现简单留言板功能
May 30 Javascript
微信小程序picker组件两列关联使用方式
Oct 27 Javascript
用javascript编写的第一人称射击游戏
Feb 25 #Javascript
极酷的javascirpt,让你随意编辑任何网页
Feb 25 #Javascript
你真的了解JavaScript吗?
Feb 24 #Javascript
SUN的《AJAX与J2EE》全文译了
Feb 23 #Javascript
js玩一玩WSH吧
Feb 23 #Javascript
用Javascript做flash做的事..才完成的一个类.Auntion Action var 0.1
Feb 23 #Javascript
javascript知识点收藏
Feb 22 #Javascript
You might like
前端开发部分总结[兼容性、DOM操作、跨域等](持续更新)
2010/03/04 Javascript
杨氏矩阵查找的JS代码
2013/03/21 Javascript
jquery点击页面任何区域实现鼠标焦点十字效果
2013/06/21 Javascript
JavaScript实现在数组中查找不同顺序排列的字符串
2014/09/26 Javascript
提升PHP安全:8个必须修改的PHP默认配置
2014/11/17 Javascript
JavaScript 封装一个tab效果源码分享
2015/09/15 Javascript
jQuery操作动态生成的内容的方法
2016/05/28 Javascript
基于jQuery实现仿百度首页选项卡切换效果
2016/05/29 Javascript
JS之获取样式的简单实现方法(推荐)
2016/09/13 Javascript
使用bootstrap validator的remote验证代码经验分享(推荐)
2016/09/21 Javascript
值得分享的JavaScript实现图片轮播组件
2016/11/21 Javascript
js实现键盘自动打字效果
2016/12/23 Javascript
webpack2.0配置postcss-loader的方法
2017/08/17 Javascript
使用 Angular RouteReuseStrategy 缓存(路由)组件的实例代码
2019/11/01 Javascript
JavaScript如何实现图片处理与合成
2020/05/29 Javascript
[05:53]完美世界携手游戏风云打造 卡尔工作室观战系统篇
2013/04/22 DOTA
[02:53]2018年度DOTA2最佳战队-完美盛典
2018/12/17 DOTA
Mac OS X10.9安装的Python2.7升级Python3.3步骤详解
2013/12/04 Python
python实现数值积分的Simpson方法实例分析
2015/06/05 Python
python批量添加zabbix Screens的两个脚本分享
2017/01/16 Python
python 实现在Excel末尾增加新行
2018/05/02 Python
Python视频爬虫实现下载头条视频功能示例
2018/05/07 Python
Python OrderedDict的使用案例解析
2019/10/25 Python
python爬虫之遍历单个域名
2019/11/20 Python
python实现从wind导入数据
2019/12/03 Python
Django集成celery发送异步邮件实例
2019/12/17 Python
python+selenium 脚本实现每天自动登记的思路详解
2020/03/11 Python
详解python tcp编程
2020/08/24 Python
通过代码实例了解Python3编程技巧
2020/10/13 Python
BONIA官方网站:国际奢侈品牌和皮革专家
2016/11/27 全球购物
美国网上鞋子零售商:Dr. Scholl’s Shoes
2017/11/17 全球购物
手工制作的男士奢华英国鞋和服装之家:Goodwin Smith
2019/06/21 全球购物
小学生优秀评语大全
2014/04/22 职场文书
学生偷窃检讨书
2014/09/25 职场文书
2014乡党委副书记党建工作汇报材料
2014/11/02 职场文书
门店店长岗位职责
2015/04/14 职场文书