function doV(mc1, mc2, mc3) {// r指的就是mc1的运动半径:
var r= Math.sqrt(mc2.m*mc2.m+mc3.m*mc3.m+mc2.m*mc3.m)/(mc1.m+mc2.m+mc3.m)*a;
mc1.v = Math.sqrt(mc1.fs*r/mc1.m); //根据向心力求匀速圆周运动速度
}
程序清单:
#include "Physics.as"
_root.onLoad=function(){
ball1.CreateBasicPhysicsFeature(1,0,0,0);
ball2.CreateBasicPhysicsFeature(1,0,0,0);
ball3.CreateBasicPhysicsFeature(1,0,0,0);
for(var i=1;i<4;i++){
eval("ball"+i).CreateExtendMotionFeature(0,0,0,0);
eval("ball"+i).ForceCondition(0,0,0,0);
eval("ball"+i).ForcedirectionX(0);
eval("ball"+i).ForcedirectionY(0);
eval("ball"+i).VdirectionX(0);
eval("ball"+i).VdirectionY(0);
eval("ball"+i).ForcedirectionX(0);
eval("ball"+i).ForcedirectionY(0);
eval("ball"+i).fs(0);
eval("ball"+i).fx(0);
eval("ball"+i).fy(0);
}
G = 1000;
a = 100;//三者呈三角状态时的参数。
}
///***Fundamental Function***///
function Getdistance(mc1, mc2) {
return Math.sqrt((mc1._x-mc2._x)*(mc1._x-mc2._x)+(mc1._y-mc2._y)*(mc1._y-mc2._y));
}
//b)计算出MC1到MC2的单位方向向量:
function StardandlizeAngle(mc1, mc2) {
var l = Getdistance(mc1, mc2);
mc1.ForcedirectionX=(mc2._x-mc1._x)/l;
mc1.ForcedirectionY=(mc2._y-mc1._y)/l;
}
function normal_vector(mc1){//求MC1沿顺时针绕MC2转的法向单位向量。
mc1.VdirectionX=mc1.ForcedirectionY;
mc1.VdirectionY=-mc1.ForcedirectionX;
}
function doForce(mc1,mc2) {//注意之里采用的累加力的方式
var r = Getdistance(mc1, mc2);
StardandlizeAngle(mc1, mc2);
var tempForce = G*mc1.m*mc2.m/(r*r);
mc1.fx += mc1.ForcedirectionX*tempForce;
mc1.fy += mc1.ForcedirectionY*tempForce;
}
function return_fx_fy(){//每一帧的最后,把力归零。
var i=1;
while(i<4){
eval("ball"+i).fx=0;
eval("ball"+i).fy=0;
i++;
}
}
function doFsum(mc){
mc.fs=Math.sqrt(mc.fx*mc.fx+mc.fy*mc.fy);
}
function doV(mc1,mc2,mc3){
var r=Math.sqrt(mc2.m*mc2.m+mc3.m*mc3.m+mc2.m*mc3.m)/(mc1.m+mc2.m+mc3.m)*a
mc1.v=Math.sqrt(mc1.fs*r/mc1.m);
}
function doMove_Circle(mc){
mc.ForcedirectionX=mc.fx/mc.fs;
mc.ForcedirectionY=mc.fy/mc.fs;
normal_vector(mc);
mc.vx=mc.v*mc.VdirectionX;
mc.vy=mc.v*mc.VdirectionY;
mc._x+=mc.vx;
mc._y+=mc.vy;
}
///Combine Functions and do Motions///
function sumForce(){
for(var i=1;i<4;i++){
var j=1;
while(j<4){
if(i!=j){
doForce(eval("ball"+i),eval("ball"+j));
}
j++;
};
}
}
function CaculateF(){
sumForce();
var j=1;
while(j<4){
doFsum(eval("ball"+j));
j++;
}
}
function CaculateV(){
doV(ball1,ball2,ball3);
doV(ball2,ball1,ball3);
doV(ball3,ball1,ball2);
}
function SumMove(){
var i=1;
while(i<4){
doMove_Circle(eval("ball"+i));
i++;
}
}
_root.onEnterFrame=function(){
CaculateF();
CaculateV();
SumMove();
return_fx_fy();
}
演示:三球的质量相等(不过好心中心点有小的偏移,望高人指点)
UploadFile/2004-8/200482115545747.swf
小结:
所以,我们可以看到,当我们的函数及构建的物理属性自成为一个体系的时候,实现物理现象变得越来越清楚而方便了,关键就是在于作好物理状况的分析,需要求哪些量,按怎样的一个顺序来操作,这些,少了任何一环,都会导致实验的失败。所以,比较扎实的物理水平,是作好这些实验的前提(自夸J).让后,只要想好想关的函数,如何进行调用,哪些需要反复调用,哪些只需要调用一次。(建议先在纸上写好,可以省去大量不必要的调试时间)再定义好相关的开关变量,以及将效果整合在一起的函数,往onEnterFrame中一放,哈哈,成功了。
大家可以看到,有了上述这些物理模型,很多flash小游戏的核心部分都已经解决了,如:
撞砖块(复制砖块+反弹方程+失败成功判定PS:小横杆在边缘处碰小球时返弹是照原路径回去),
射泡泡(射完后泡泡一变二+返弹判定+失败成功判定),
欢乐碰碰车(把小球碰撞实验里的碰撞系数改一下就会有很棒的效果了。)
做这些游戏起来是不是变得得心应手了?我有空一定要把这些小游戏都做一下,毕竟,用的是自家的体系,自成一派,感觉就是不一样。
好了,由于时间的关系,这次的专题就介绍到这里,我自已经列了一张表,还有一大堆激动人心的物理摸拟实验要作,这里,伴随着的,也是更高要求的编程能力,数学能力以及物理知识(比方说:把Vector类加入mc类中,用一个向量v便可代替两个分量vx,vy,还有:三维视觉效果的能实现话,那迎来的将是更为广阔的空间,更高级的碰撞检测要用到离散数学)希望高人能能有所指点。我会继续努力下去的,只因为在FLASH里,是我的梦想真正开始的地方……