在flash坐标体系中(即舞台上),放上一个点a,然后通过a点将a点的x,y长度画出来,并将两条线的端点连起来,你看一个直角三角形出现了。这样三角函数就有研究头了。这个三角形跟这个点有什么关系呢?最明显的就是这个三角形的两条直角边b,c确定了a点的位置。除了两条直角边以外,还有斜边d,还有一个角e, (另外两个角我们不研究)。这些边和角之间的关系就是三角函数。我们说过只研究三个函数:
sin(e) = c/d; 对边除以斜边
cos(e) = b/d; 邻边除斜边
e = atan(c/b)
而flash为我们提供了一个更为合理的反正切函数:atan2(y,x)
即: e = atan2(y,x)
从上面的图中可以看出,实际上b就等于点a的x,c就等于点a的y.这换一下,就成:
sin(e)=y/d;
cos(e) = x/d;
将这两个式子变一下就成:
y = d*sin(e);
x=d*cos(e);
对这两个式子,需要说明的是:角e在三角函数的运行中必须使用弧度制,这与我们习惯的角度制有所不同,所以我们需要记住角度弧度转换的公式:
[cose]角度弧度转换公式:
角度 = 弧度*180/Math.PI;
弧度 = 角度*Math.PI/180;[/code]
PI是园周率,即3.14159,它属于Math类写法为:Math.PI.三角函数也属于Math类。所以上面的公式正确写法是:
x= d*Math.cos(e) e为弧度表示
y=d*Math.sin(e)
三角函数的知识差不多复习这么多就行了,是不是很简单呢?
园周运动:
(本文来源于图老师网站,更多请访问https://m.tulaoshi.com/flash/)上面介绍的三角函数有什么用呢?我们还是来看看前面那个图,如果直角三角形的斜边长度固定不变,让角e不断地加大,会是个什么效果呢?很容易理解它出现的是下面的效果:
点a在做园周运动。看起来有点意思了哈。怎样让它做园周动运的呢?要让对象移动需要改变对象的x,y值,上面的公式已经给了我们计算这两个值的方法:
x= d*Math.cos(e)
y=d*Math.sin(e)
做园周运动时直角三角形的斜边长度d不变,其实我们早已看出来了,斜边实际就上园周的半径。将角e不断增大,从而产生不同的x,y值,将这些值赋给点a对象,就形成了园周运动了。在上例中,我们将点a做成MC,实例名称为:ball_mc,h 上例的代码为:
var d = 100; //半径为100
var centerx = Stage.width/2;
var centery = Stage.height/2;确定园心的位置在舞台中心
var zl=10;//设一个增量,即角e每次增加10度。
var i=1;
onEnterFrame =function(){
ball_mc._x=centerx+d*Math.cos(i*zl*Math.PI/180);//再次提醒三角函数要用弧度
ball_mc._y =centery+d*Math.sin(i*zl*Math.PI/180);
i++;
if(i36){//这个条件语句可以不要,但那样i会无限度增大,我觉得不好,所以在i36时,即转完1周时,让i=1。
i=1;
}
}
上面已经完成了三角函数的第一个应用:园周运动。
园周运动公式:
MC._x = 园心x+半径*Math.cos(i*增量*Math.PI/180);
MC._y = 园心x+半径*Math.sin(i*增量*Math.PI/180);
i++;
你非常高兴,因为你已经会让对象做园周运动了,你很快就想到了要做一个月亮围绕地球运转的效果。但问题出现了,月亮的运轨迹好象是椭园的。不要作急,我们来比较一下园和椭园的区别,很快我们发现椭园与园的区别就是x轴半径和y轴的半径不相等。于是乎,椭园运动公式出来了。
椭园运动公式:
MC._x = 园心x+x轴半径*Math.cos(i*增量*Math.PI/180);
MC._y = 园心x+y轴半径*Math.sin(i*增量*Math.PI/180);
i++;
恭喜,你现在连椭园运动都会了。我们再来研究一下,看看三角函数还能搞点什么名堂。
上面说过,要研究三个三角函数,上面只用了两个,好象还有个flash专用的反正切函数:atan2.这个函数是根据某点的x,y值计算出该点与x轴之间的角度:
e = Math.atan2(y,x);
能不能算出两点之间的角度偏差呢?还是来看看图:
在图中有两个点a和b,将两个点用一根线连起来,通过a点作y轴平行线,通过b点作x轴平行线,这样三根线就组成了一个直角三角形。有了三角形就好办了,我们的三角函数就该上场了。先来分析一下这个直三角形,不难看出,三角形的两条直角边实际就是两点的坐标差,分别是:(x1-x2)和(y1-y2).而角e就是是两点间的角度差。有了角度差,就想如果将b点旋转一个角差,那么b点的方向就与a点一样了。如果将a点换为鼠标,在鼠标移动时始终计算b点与鼠标的角差,然后让b点旋转这个角差,这样b点会一直指向鼠标跑都跑不脱。效果如下:
代码:
onEnterFrame = function(){
var dx = _xmouse - jt_mc._x;
var dy = _ymouse - jt_mc._y;
var angle = Math.atan2(dy,dx)*180/Math.PI;
jt_mc._rotation = angle;
}
跟随鼠标旋转公式:
onEnterFrame = function(){
var dx = _xmouse - MC._x;
var dy = _ymouse - MC._y;
var angle = Math.atan2(dy,dx)*180/Math.PI;
MC._rotation = angle;
}
这里要注意两点:1. atan2(dy,dx)是dy在前,dx在后,这一点容易搞错。2.由atan2()计算出的角度是弧度,而我们要设置_rotation属性要用角度,所以要用180/Math.PI;弧度转为角度。硬是妖怪得很,一会转过去,一会转过来。
现在你又想出了新花样了,光是跟着鼠标转还不行,还跑过去抓住它。还是看上面那个图,b点要到a点,是不是b点的x加上(x1-x2), b点的y加上(y1-y2)就行了呢。但即然是跟跟随肯定不能一步到位,要不就不是跟随了,而是帖在一起了,也就是说趋于直角三角形的斜边一能一步到位,而是一点一点地增加,这就需在设一个增量。根据前面的三角函数公式就可算出每次增加的x和y的量了。
vx = 增量*Math.cos(e);
vy = 增量*Math.sin(e);
将b点的x,y不停地加上这个vx,vy,b点就不停地向a点靠近了。
效果:
代码:
var speed = 3;
onEnterFrame = function(){
var dx = _xmouse - jt_mc._x;
var dy = _ymouse - jt_mc._y;
var angle = Math.atan2(dy,dx)*180/Math.PI;
jt_mc._rotation = angle;
jt_mc._x += speed*Math.cos(angle);
jt_mc._y += speed*Math.sin(angle);
}
鼠标跟随公式:
var speed = 一个数字;
onEnterFrame = function(){
var dx = _xmouse - MC._x;
var dy = _ymouse - MC._y;
var angle = Math.atan2(dy,dx)*180/Math.PI;
MC._rotation = angle;
MC._x += speed*Math.cos(angle);
MC._y += speed*Math.sin(angle);
}
将本节介绍的内容与上节介绍的绘图方法结合,可以绘制出很多图形,如园,椭园,正,余弦波形等。这个留给大家研究。下面做一个经典的练习,图片旋转,制作方法来源于网络:
下面是我的鼠绘作品的一个算是展示吧:
我选了6张作品,导入到库中。然后,新建一个MC,共6个关键帧,每个关键帧,放一张图片,大小统一调为150x200.然后在库中右击MC连接,点中为ActionSpript运行时导出前的钩,在标识符一栏内输入:imge.
回到主场景,打开帧动作面板,输入:
var r = 200;
var v = 1;
for (var i = 1; i=6; i++) {
attachMovie("imge", "mc"+i, i);
_root["mc"+i].gotoAndStop(i);
_root["mc"+i].cita = i*60;
_root["mc"+i]._y = 200;
}
onEnterFrame = function () {
v = (275-_root._xmouse)/25;
for (var i = 1; i=6; i++) {
with (_root["mc"+i]) {
cita += v;
_alpha = 50+(100+100*Math.sin(cita/180*Math.PI))/4;
_xscale = 100*Math.sin(cita/180*Math.PI)*_alpha/100;
_yscale = 75+(100+100*Math.sin(cita/180*Math.PI))/8;
_x = 75+r-r*Math.cos(cita/180*Math.PI);
}
_root["mc"+i].swapDepths(Math.round(_root["mc"+i]._xscale));
}
};
代码分析:
首先通过一个for循环,将图片元件加载6次,每一次加载后,让它停在不同的帧上,这样舞台上实际上就有6张不同的图片了,这是一个非常有趣的方法,值得学习。同时为每张图片设置了一个不同的初始量Cita,共6张图片,一个园周是360度除以6等于60,这样6张图片被设为i*60,即均匀分布。最后将图片的y坐标固定在200,因为图的旋转实际就是图片从左到右往返运动而已,y坐标是不变的。
for (var i = 1; i=6; i++) {
attachMovie("imge", "mc"+i, i);
_root["mc"+i].gotoAndStop(i);
_root["mc"+i].cita = i*60;
_root["mc"+i]._y = 200;
}
接下来的代码可能不是太好理解,请记住一点,正弦,余弦函数的值是从1到-1来回变化的,这一点很重要,在下面的代码中充分地运用了这个原理。通过 onEnterFrame事件使动画不断重复,每重复一次,每一个图片的Cita加上鼠标x坐标与舞台中线的差值除25,也就是说设置了一个增量,所以这 25可以自行改变,值越大转得越慢。
onEnterFrame = function () {
v = (275-_root._xmouse)/25;
for (var i = 1; i=6; i++) {
with (_root["mc"+i]) {
cita += v;
接下来设置图片的透明度,来理解一下这句:
_alpha = m.tulaoshi.com50+(100+100*Math.sin(cita/180*Math.PI))/4;
首先看:Math.sin(cita/180*Math.PI)这个函数的值上面说了是从1到-1来回变化的。那么100*Math.sin(cita /180*Math.PI)10到-100来回变化,100+100*Math.sin(cita/180*Math.PI))就是200到0之间的变化了,(100+100*Math.sin(cita/180*Math.PI))/4就是50到0之间变化了,50+ (100+100*Math.sin(cita/180*Math.PI))/4;就是50到100之间变化了。这一句的作用就是使透明度在正面时为 100,转到背面时为50.
接下来:
_xscale = 100*Math.sin(cita/180*Math.PI)*_alpha/100;
100*Math.sin(cita/180*Math.PI)的值是100到-100,_xscale属性设为-100时的效果是水平翻转,这就形成了在正面的背面方向不一样的效果,也行成了在两端时的翻转效果。*_alpha/100;应该是让图片的正反面与透明度同步。
下一句:
_yscale = 75+(100+100*Math.sin(cita/180*Math.PI))/8;
算得出来这是让图片的高在75到100之间变化,即在背面时高度要小一些。
下一句:
_x = 75+r-r*Math.cos(cita/180*Math.PI);
可以算出等号后面的式子值为75到475之间变化,这就确平方和了图片在75到475间左右移动。
最后一句:
_root["mc"+i].swapDepths(Math.round(_root["mc"+i]._xscale));
深度交换,让图片在最大时(正面),在最上面,以形成正面图片遮住背面图片的效果。