实现的初级物理模型的构建(力学-1)
EmilMatthew(小小梦想) 2004.8.21
阅读本文之前,假定你已有了:
基本的编程能力,初步了解OOP。
高中及以上的程度物理及数学知识。
推荐能力:会基本的AS编程。
序:
由于我打算把这样一个专题长期作下去,所以有些东西必须事先关照一下,以后的文章中就不再讲了。
1为何选用ActionScript?
ActionScript是矢量动画制作软件Flash的动画脚本语言,现在已经发展到了OOP(面象对象编程)层面,与动画对象的结合是极其方便而直接的,完全可以满足我现在所想做的一些动态效果演示的要示。(而我用到的,也只是AS1,由于我的编程能力有限,目前AS2我还不会。)
我这里用的OOP方法,学习的是Robert Peneer那本“Flash MX 编程与创意”所介绍的方法,非常的简单易用:
如在AS脚本中写:
MovieClip.prototype.v=function(x){
This.v=x; }
便使得MC类扩展了一个速度v的属性,这是非常有用的,也是OOP初级应用中最具有魅力之处(给原有的类添加属性及方法)
在场景的AS里:
只要用 mc.v(5);便创建了其速度属性,注意,一定要先创建,否则在下面使用时,会出现Undefined的错误。
这里其实是用到了一个方法,这个方法就是传送参数,给MC对像的v属性,非常的简单易用。
创建完之后,下面进行数值上的计算时。
用mc.v=…..的形式就可以了。
有人会说了,何必这样呢,我只要根据我的需要,在程序中创建相应的属性不就行了吗?这在问题比较简单时和只作一个独立的效果时当然没问题。而当问题变的复杂时,同时你又需要在这个方面“长期作战”时,构建相应的函数库就显得犹为重要了 。比方说,我构建了自己的物理属性库,可以使一些物理数据表达和处理更为“固化”,更能成为一个体系,使程序更具有移植性,更有利于实现物理现象的动态演示。
比方说,我准备给七个对象分别创建v,m,a(加速度),r(半径)四个物理属性,只消在
AS脚本里写:
MovieClip.prototype.CreateBasicPhysicsFeature=function(m,v,a,r){
this.m(m);
this.v(v);
this.a(a);
this.r(r);
}//假定先前已经写好的构建属性m,v,a,r 的
场景中构造时只消这样就行了:
while(i<8){
eval(“ball”+i).CreatBasicPhysicsFeature(1, 1,1,1); }
是不是很方便呢?
下面是我目前为实现效查所构建的物理函数库:(扩建中)04/8/19
点击浏览该文件
2计算机的计时方式及误差的调整:
现实世界中的时间连续的,不可被分割的,而在计算机中动态效果的实现是以帧频为单位的,在摸拟时必定会有一定的误差出现。
举个例子,假定有一堵透明的墙(去掉了其硬度的物理属性),规定只要有物体碰到它,该物体就会被返弹回去。在现实世界中,这是必定可以实现的,因为时间是连续的;而到了计算机里,则很可能出现物体飞入墙中,又被弹回的情形,因为时间以帧频是以帧率为单位,是间隔的。前一帧做检测时,物体距墙还有1个单位,而其速度为10单位/帧并朝向墙飞去,则下一帧必定会有球入墙中的不足发生。所以,物理问题简单时,做必要的调整是可行而且是很重要的的,如:自由落体时,在碰底时加一个:
mc._y=buttom+mc._height/2 //未经说明,以后的mc的_x,_y的注册点都是mc的中间。
便是一个很好的误差调整,否则会因为每次误差的不断累积,而出现球穿出地面的BUG。
以下是程序清单:
if (mc.getBounds(_root).yMax>=600) {
mc._y = 600+mc._height/2;;
// Important!否则会因为微小的积累而导致质变---穿出地面。
mc.v *= -0.9;
// 还是有点衰减为好。 }
物理问题复杂时,这种误差的调整就显得很难了。当然,路是人走出来的,只要你的数学水平,物理水平和编程能力都跟上去的话,这些误差是一定可以降到最小限度,只不过,这现在对我,还是个比较高远的目标。
3单位:
速度单位在这里,很显然是“像素/帧”,所以,把动态效果放在每帧更新一次的onEnterFrame事件处理器(也可以用SetInterval)中,写下:v+=a ; _x+=v;是很合理的。
4不符要求的两类动画:
一种是帧频过低的动画,看起来是一格一格的,出现这种情况时,就要考虑是否是由于算法不良造成了运行过缓,还是在图片上消耗了过多的内存,必须进行改进。
第二类是运动过快的动画,如何一个物体在屏幕上的运动速度高达100像素/帧,而你的帧频又在30FPS以上,那么,此时,物体的运动变成的转瞬即逝,看都看不清了,更别谈什么碰撞检测之类的了。
帧频可能的话,当然是希望高些,因为这样的话,无论是动态摸拟还是碰撞检测,都会更精确,一般摸拟器的帧频都是60FPS,这样的帧频要求在Flash里太高了,不过倒也好,可以更加激励我们脚踏实地的去优化代码,改过算法。
PS:由于word里的格式问题,会造成极少部分语句造成不符合AS的语法规则,如else if显示成elseif ,敬请谅解。 好,关照完这些注意事项后,下面进入正题:
物理背景―――完全弹性碰撞的方程:
在AS中构造的collision 方程便是这样:
a)相对速度的写法:(计算更快)
function collision(mc1,mc2){
var v1temp=mc1.v;
var v2temp=mc2.v;
mc1.v=((mc1.m-mc2.m)/(mc1.m+mc2.m))*v1temp+(2*mc2.m/(mc1.m+mc2.m))*v2temp;
mc2.v=v1temp-v2temp+mc1.v; }
b)完全的套用公式:
function collision(mc1,mc2){
var v1temp=mc1.v;
var v2temp=mc2.v;
mc1.v=((mc1.m-mc2.m)/(mc1.m+mc2.m))*v1temp+(2*mc2.m/(mc1.m+mc2.m))*v2temp;
mc2.v=(2*mc1.m/(mc1.m+mc2.m))*v1temp-((mc1.m-mc2.m)/(mc1.m+mc2.m))*v2temp; }
c)加入了非弹性碰撞系数的碰撞函数:
function collision(mc1,mc2){//注意应用到程序中时看看是否要改成vx,vy等。
var e=1;//e的范围由0--1。
var v1temp=mc1.v;
var v2temp=mc2.v;
mc1.v=((mc1.m-e*mc2.m)/(mc1.m+mc2.m))*v1temp+((1+e)*mc2.m/(mc1.m+mc2.m))*v2temp;
共有 0 位网友发表了评论,得分 0 分,平均 0 分 查看完整评论