好了下面开始分析代码如何写的了,先看一个图

看得出,我是用分界面和法线把场景分成了4个区域,相当于数学里的第一到第四象限,在代码中先作了如下的初始化
fjm._y = 200;
fx._x = 250;
//以上可知交点相当于坐标原点为(250,200)
//折射光线、反射光线的x、y坐标分别在250,200(即坐标原点)
zs._x = 250;
zs._y = 200;
fs._x = 250;
fs._y = 200;
由以上的初始化可知,折射光线、反射光线的注册点必须在左边(看元件制作)同时由图可知,入射光线只能在3、4象限,意味着光源只能在3、4象限移动,所以光源(激光jg)元件只能在平面以下拖动,左右最好不要出场景,代码为
this.startDrag(true, 0, 200, 500, 500);
接下来就要解决入射角和折射角的关系,还是再看一个图

这个截图中入射光线是在第三象限,对应的折射光线在第一象限,而flash的旋转用其属性_rotation实现,这个属性表示的是指定影片剪辑相对于其原始方向的旋转程度,以度为单位。从 0 到 180 的值表示顺时针方向旋转;从 0 到 -180 的值表示逆时针方向旋转。所以首先要获得入射光线的旋转角A,可我们上面的元件中没有入射光线呀,怎么来的,实际上是用以下代码画的
this.createEmptyMovieClip("mc", 100);
mc.lineStyle(2, 0xff0000, 100);
mc.moveTo(250, 200);
x = jg._x;
y = jg._y;
mc.lineTo(x, y);
那么,A就可以用反三角函数获得代码为
A = Math.atan2(y-200, x-250);
从图中可知,其真正的入射角为r = A-Math.PI/2;其折射角i = Math.asin(1.5*Math.sin(r)) 从图中可知折射光线旋转的角度应该为-90+i*180/Math.PI,相应代码为
if (x<250) {
r = A-Math.PI/2;
if (r<C) {
i = Math.asin(n*Math.sin(r));
zs._rotation = -90+i*180/Math.PI;
zs._alpha = 100-i*60;
} else {
zs._alpha = 0;
}
大家可能会问,zs._alpha = 100-i*60;这一句的算法是如何的,根据物理规律,当折射角越大,其能量越小,当折射为90度时发生全反射,对应的折射光线能量为零,在动画中反映为其_alpha值越来越小,按实际计算为zs._alpha = 100-i*63.7的,但考虑实际效果,算了,就这样吧。反之反射光线能量越来越大,当发生全反射时,能量最大,等于入射光的强度,用代码fs._alpha = i*60实现,怎么样,清楚吗?
剩下的是当入射光线在第四象限时的了,也看一下类似的图

对应代码如下
} else if (x>250) {
r = Math.PI/2-A;
if (r<C) {
i = Math.asin(n*Math.sin(r));
zs._rotation = -90-i*180/Math.PI;
zs._alpha = 100-i*60;
} else {
zs._alpha = 0;
}
}
最后解决最简单的反射光线的旋转问题,其实由倒数第三个图很容易得其代码为
fs._rotation = 180-A*180/Math.PI;