教程
先说明,本教程仅为学习交流之用,任何人不经本人允许不得使用其进行商业用途.
大致的最终结果:
问题分析,主要的重点在两个方面,一个是动力学模型的建设,一个是如何绘制圆滑的曲线.首先关于曲线,先参照第1个例子,里面的代码很简单.http://www.webjx.com/upfiles/20070417/20070417213136_webjx_com_01.flahttp://www.webjx.com/upfiles/20070417/20070417213150_webjx_com_01.swf
this.createEmptyMovieClip("circle_mc", 1);
this.onEnterFrame = function () {
with (circle_mc) {
clear();
lineStyle(0, 0x000000, 100);
moveTo(275, 150);
curveTo((275+_xmouse)/2,(150+_ymouse)/2+50,_xmouse,_ymouse);
}
}整个代码很简单,只是用于画一条跟随鼠标的贝塞尔曲线而已.
其中最主要起作用的语句为2条:
moveTo(275, 150); //是画图起点(红点)
curveTo((275+_xmouse)/2,(150+_ymouse)/2+50,_xmouse,_ymouse);绘制一条曲线,其中终点坐标为:_xmouse,_ymouse(蓝点). 控制点坐标为: (275+_xmouse)/2,(150+_ymouse)/2+50 (黑点).
如果你认为你确实已经弄懂了这三个点的关系,可以接着往下看.下面的问题是建立动力学模型.这里建立的是一个基于经典物理学的简要模型,不牵涉微积分什么的.
好,打开第两个例子,场景中有3个点:
分别是原点,实例名:yuandian.红色
中心点,实例名:zhongxindian.蓝色
鼠标点,实例名:shubiaodian.绿色
http://www.webjx.com/upfiles/20070417/20070417212136_webjx_com_02.flahttp://www.webjx.com/upfiles/20070417/20070417212319_webjx_com_02.swf
然后在帧上写AS:
this.createEmptyMovieClip("_mc", 1);
tx=0;ty=0;
ax=0;ay=0;
i=7;
q=0.81;
lenmax=220;
r=0.2;
pianyi=0;以上全部为参数,暂时先不必理会.
this.onEnterFrame = function () {
shubiaodian._x=_xmouse;
shubiaodian._y=_ymouse;//把鼠标点元件绑在鼠标上,当然你用drag也行,效果一样.
//lenx=shubiaodian._x-yuandian._x;
//leny=shubiaodian._y-yuandian._y;
//len=Math.sqrt(lenx*lenx+leny*leny);
//pianyi=(lenmax-len)*r;
//if (pianyi<0) pianyi=0;
//该部分计算偏移的暂时先不理会
ax=((yuandian._x+shubiaodian._x)/2-zhongxindian._x)/i;
//此语句是计算中心点在水平方向上的加速度,默认的,中心点应该在原点和鼠标点的中心.所以,用中心点的"目的坐标"减去"实际坐标"再乘上一个系数,就可以得到中心点在水平方向上的加速度.
ay=((yuandian._y+shubiaodian._y)/2-zhongxindian._y+pianyi)/i;
//在Y值上一样的道理,只不过中心点的坐标会稍微向下偏移,以形成重力的感觉.其中偏移量的计算随后解释.
tx +=ax;//计算中心点在水平方向上的速度变化,就是让速度加上加速度.
ty +=ay;//同上,纵向上的
tx *=q; //让中心点的速度逐渐衰减,以使它出现慢慢停止的效果.你可以试着把q值改为1或0试下.
ty *=q; //同上
zhongxindian._x +=tx; //让中心点移动,水平方向上移动tx点.
zhongxindian._y +=ty; //让中心点移动,垂直方向上移动ty点.
with (_mc) {
clear();
lineStyle(0, 0x000000, 100);
moveTo(yuandian._x, yuandian._y);
lineTo(zhongxindian._x, zhongxindian._y);
lineTo(shubiaodian._x, shubiaodian._y);
lineTo(yuandian._x, yuandian._y);
}
//以上画线(直线),很简单,不赘述.
}
这样一个简单的动力学模型就出来了.但是如果没有偏移量的计算的话,中心的坐标将始终在原点和鼠标点的正中央.所以需要计算一下Y方向上的偏移量.所谓的偏移量就是指中心点偏靠下方的距离.简单的概括下,偏移量有个特色,因为是软力绳,所以原点和鼠标点越近,这个值就应该越大,反之越小.我们简单的把这个用线形来描述.比如绳子的最大长度是:lenmax=220;
lenx=shubiaodian._x-yuandian._x;
leny=shubiaodian._y-yuandian._y;
len=Math.sqrt(lenx*lenx+leny*leny); //以上语句计算原点和鼠标点的距离len,当然你可以用point类来算更方便,但我这里保持了初中几何的写法.
pianyi=(lenmax-len)*r;
if (pianyi<0) pianyi=0; //计算偏移量,如果发现为负的话,则让其为0.
接下来画线,问题很简单,把直线换成曲线就是.
http://www.webjx.com/upfiles/20070417/20070417212501_webjx_com_03.flahttp://www.webjx.com/upfiles/20070417/20070417212603_webjx_com_03.swf前面的代码相同
with (_mc) {
clear();
lineStyle(0, 0x000000, 100);
moveTo(yuandian._x, yuandian._y);
kongzhidian1_x=(yuandian._x+zhongxindian._x)/2-tx;
kongzhidian1_y=(yuandian._y+zhongxindian._y)/2+pianyi/2-ty;
//以上语句就是定位控制点1的坐标,先简单的用前面例1中的算法.
curveTo(kongzhidian1_x,kongzhidian1_y,zhongxindian._x, zhongxindian._y);
kongzhidian2_x=(zhongxindian._x+shubiaodian._x)/2-tx;
kongzhidian2_y=(zhongxindian._y+shubiaodian._y)/2+pianyi/2-ty;
curveTo(kongzhidian2_x,kongzhidian2_y,shubiaodian._x, shubiaodian._y);
//以上语句就是定位控制点2的坐标,先简单的用前面例1中的算法.
}这样算出来的结果有瑕疵,很明显中心点不是一个圆角,而显现出了棱角的特点,这和软力绳的样子不符合.这时需要回到例1中去分析.这里不去分析贝塞尔曲线的公式,这里简单的把结论说一下.很显然当一条曲线画完后,接着的第二曲线的切线应该和前一个曲线相切,也就是说,第二条曲线的控制点应该与前一条曲线的控制点以及中心点在一条直线上,或者说他们斜率相同.(看图上呈一条直线的3个点)
OK,到例4中,相关的代码换了一下.http://www.webjx.com/upfiles/20070417/20070417213505_webjx_com_04.swfhttp://www.webjx.com/upfiles/20070417/20070417213432_webjx_com_04.fla
http://space.flash8.net/bbs/attachment.php?aid=321430
http://space.flash8.net/bbs/attachment.php?aid=321431
with (_mc) {
clear();
lineStyle(0, 0x000000, 100);
moveTo(yuandian._x, yuandian._y);
kongzhidian1_x=(yuandian._x+zhongxindian._x)/2-tx*2;
kongzhidian1_y=(yuandian._y+zhongxindian._y)/2+pianyi/2-ty;
//kongzhidian1._x=kongzhidian1_x;
//kongzhidian1._y=kongzhidian1_y;
//lineTo(kongzhidian1_x,kongzhidian1_y);
//moveTo(yuandian._x, yuandian._y);
curveTo(kongzhidian1_x,kongzhidian1_y,zhongxindian._x, zhongxindian._y);
len2_x=zhongxindian._x-shubiaodian._x;
len2_y=zhongxindian._y-shubiaodian._y;
len2=Math.sqrt(len2_x*len2_x+len2_y*len2_y);
lent_x=kongzhidian1_x-zhongxindian._x;
lent_y=kongzhidian1_y-zhongxindian._y;
lent=Math.sqrt(lent_x*lent_x+lent_y*lent_y);
kongzhidian2_x=zhongxindian._x-len2*lent_x/lent*p1;
kongzhidian2_y=zhongxindian._y-len2*lent_y/lent*p1;;
//kongzhidian2._x=kongzhidian2_x;
//kongzhidian2._y=kongzhidian2_y;
//lineTo(kongzhidian2_x,kongzhidian2_y);
//moveTo(zhongxindian._x, zhongxindian._y);
curveTo(kongzhidian2_x,kongzhidian2_y,shubiaodian._x, shubiaodian._y);
}没时间解释代码了,简单的来说就是延着延长线放置第二个控制点.这样一个简单的软力绳就出来了.大概修整一下相关参数,最后的结果例5.
http://www.webjx.com/upfiles/20070417/20070417212723_webjx_com_05.swfhttp://www.webjx.com/upfiles/20070417/20070417213702_webjx_com_05.fla
这是最简单的软力绳,仅仅做到模仿,想体现更复杂的效果的话,请自行研究相关的算法,并设置更多的中心点.