本页面由 Flash 保存计划 从 Internet Archive 存档还原 · 快照 2004-12-09 · 原址 http://www2.flash8.net/teach/654.htm ← Flash 保存计划
 
鬼火的AS画线教程
作者:  
时间: 2004年4月5  类型: 原创  
收藏 发送 评论 <%=votevote%>打印 字体选择:   

讲之前要线说明一点,前面的几个画线方法是我从闪吧的as区转过来的,目的是为了让初学者更加清楚的认识几个画线方法的功能.为了更加的易懂,我加上了一些注解------就这点而言,版主同志,转的几张贴还是要加分的^_^
在flash mx中新增加了一些函数,包括linestyle这个画线线用的小函数,但是,很有用.
昨天我在老闪吧的论坛里面看见几个高手的贴,于是转贴过来就.
(有多高?,60贴可以在老论坛25分,呵呵)
不说废话,开工
大家先看看他的演示动画,
使用了颜色,线条等多种函数和方法.
效果演示:

点击浏览该文件
源文件:

点击浏览该文件



as粗略解析:
i = 1;
//建立色块,排列色块
for (r=0; r<=0xFF; r += 0x33) {
for (g=0; g<=0xFF; g += 0x33) {
for (b=0; b<=0xFF; b += 0x33) {
dye.duplicateMovieClip("d"+i, i);
cc = new Color(eval("d"+i));
eval("d"+i)._x = 25+int((i-1)/18)*11;
eval("d"+i)._y = 20+((i-1)%18)*11;
cc.setRGB(r*256*256+g*256+b);
i++;
}
}
}
//隐藏鼠标
Mouse.hide();
//复制铅笔
pen.duplicateMovieClip("penp", 100000);
//铅笔的鼠标跟随
penp.startDrag(true);
//隐藏原有的铅笔和色快
dye._visible = false;
pen._visible = false;
//建立新的颜色对象
dyecolor = new Color(_root.penp.pencolor);
//设定初始色块颜色为黑色
dyecolor.setRGB(0);
n = 217;
p = 0;
x0 = 0;
////////////////////////////////////////////////////////////////////////////////////////
frame2 as:
这下面的乱起八遭的,我水平有限,不能完整解释,没办法,我是菜鸟
if (P == 1) {
if (X0 == 0) {
//用两个变量储存此时鼠标位置
X0 = _xmouse;
Y0 = _ymouse;
} else {
X1 = _xmouse;
Y1 = _ymouse;
X2 = _xmouse;
Y2 = _ymouse;
n = n+1;
//建立一个空的电影夹子,天知道他想干什么.
createEmptyMovieClip("xian"+n, n);
//画线线,用颜色对象里面的颜色,亮度为80
eval("xian"+n).lineStyle(2, _root.dyecolor.getRGB(), 80);
//线条初始位置设定为鼠标的当前位置
eval("xian"+n).moveTo(x0, y0);
//绘制曲线
eval("xian"+n).curveTo(x1, y1, x2, y2);
//用新的鼠标位置取代旧的鼠标位置
X0 = X2;
Y0 = Y2;
}
}
//////////////////////////////////////////////////////////////////////////////
frame3 as:
gotoAndPlay(2);
//这个难啊,要仔细讲一讲,呵呵

//////////////////////////////////////////////////////////////////////////////
第二中画线方法:
_root.createEmptyMovieClip("shape_mc", 1);
shape_mc.lineStyle(1, 0x000000, 100);
lines = new Array();
lines.cur = {x:0, y:0}; // 起始点(当前点)坐标
lines.i = -1; // 当前所画边的序号
// 每条边的终点坐标及步长
lines[0] = {x:300, y:0, dx:5};
lines[1] = {x:300, y:300, dy:5};
lines[2] = {x:0, y:300, dx:-5};
lines[3] = {x:0, y:0, dy:-5};
lines[4] = {x:100, y:-100, dx:5, dy:-5};
lines[5] = {x:400, y:-100, dx:5};
lines[6] = {x:300, y:0, dx:-5, dy:5};
lines[7] = {x:400, y:-100, dx:5, dy:-5};
lines[8] = {x:400, y:200, dy:5};
lines[9] = {x:300, y:300, dx:-5, dy:5};
shape_mc.onEnterFrame = function() {
// 如果是第一点就先定位
with (lines) {
if (i < 0) {
this.moveTo(cur.x, cur.y);
i = 0;
// 如果还有边则画边
} else if (i < length) {
cur.x += lines[ i].dx;
cur.y += lines[ i].dy;
// 判断是否过界,过界则边号加1
if (lines[ i].dx > 0 && cur.x >= lines[ i].x ||
lines[ i].dx < 0 && cur.x <= lines[ i].x ||
lines[ i].dy > 0 && cur.y >= lines[ i].y ||
lines[ i].dy < 0 && cur.y <= lines[ i].y) {
cur.x = lines[ i].x;
cur.y = lines[ i].y;
i++;
}
this.lineTo(cur.x, cur.y);
}
}
};
/////////////////////////////////////////////////////////////////////////////////
效果演示:

点击浏览该文件
源文件:

点击浏览该文件

//下面这位老大演示的是线条随时间变化增加的方法
//建立函数
function drawDream() {
//如果i没有指定(不知道怎么说好),i就被默认为0
if (i == undefined) {
i = 0;
keynum = 1;
offy = 300;
clr = new Color(pic);
//如果i被指定大于等于700
} else if (i>=700) {
//清除时间函数setInterval建立的变化
clearInterval(idDream);
}
//建立小线线
mc.lineStyle(random(++i/i/10), ++i*random(80), (i/50));
tempx += i*2*keynum/10;
//reverse set
keynum = tempx<250 ? 1 : -1;
//reverse key
tempy = 0;
offy -= .07;
//移动起始点
mc.moveTo(tempx, tempy);
mc.lineTo(tempx, tempy+offy);
var tempcolor = clr.getTransform();
tempcolor.rb += i/200;
//color to sun
tempcolor.gb += i/150;
//color to leaf
clr.setTransform(tempcolor);
}
//init
stage.scalemode = "showall";
createEmptyMovieClip("pic", 1);
createEmptyMovieClip("mc", 2);
createEmptyMovieClip("loader", 3);
pic.loadMovie("ice.jpg");
loader.onEnterFrame = function() {
if (_root.pic._width>0) {
_root.pic._width = Stage.width;
_root.pic._height = Stage.height;
this.removeMovieClip();
}
};
//init end
//start main timer
idDream = setInterval(drawDream, 10);
/////////////////////////////////////////////////////////////////////////////////
效果演示:

点击浏览该文件
源文件:

点击浏览该文件

//下面这位虾虾做的是余眩曲线,余xuan?我不知道怎么拼写啊,就用别的字代替咯,呵呵

// x, y: 中心点坐标
// kx, ky: x轴及y轴的缩放比例
// x1, x2: 波形线起止x坐标
//设定线线的粗细为0.1
linestyle(.1, 0xff0000, 100);

MovieClip.prototype.wave = function(x, y, kx, ky, x1, x2) {
if (x1 == x2 || kx == 0) {
return;
}
// 如果中心坐标和终点坐标重合(没移动)或者Y坐标没有缩放,则无效返回。
var pi_6 = Math.PI/6;
//
var i = 1;
var beginx = (x1-x)/kx;
// 开始点的相对x坐标
var endx = (x2-x)/kx;
// 结束点的相对x坐标
var curx = beginx;
// 当前点
// var nextx = beginx<endx ? (Math.floor(curx/pi_6)+1)*pi_6 : (Math.ceil(curx/pi_6)-1)*pi_6;//x坐标的间隔
// var coscx = Math.cos(curx);
// var cccsc = coscx*curx-Math.sin(curx);
// var cosnx, cnnsn, controlx, controly, anchorx, anchory;
this.moveTo(x1, y+ky*Math.sin(curx));
while (true) {
if (beginx<endx && nextx>endx || beginx>endx && nextx<endx) {
nextx = endx;
// 在所在的区间内
}
cosnx = Math.cos(nextx);
cnnsn = cosnx*nextx-Math.sin(nextx);
controlx = x+kx*(cccsc-cnnsn)/(coscx-cosnx);
// controlx=(cosx1*x1-sinx1-cosx2*x2+sinx2)/(cosx1-cosx2)
controly = y+ky*(cccsc*cosnx-cnnsn*coscx)/(coscx-cosnx);
// [(cosx1*x1-sinx1)*cosx2-(cosx2*x2-sinx2)*cosx1]/(cosx1-cosx2)
anchorx = x+kx*nextx;
anchory = y+ky*Math.sin(nextx);
// 函数本身
this.curveTo(controlx, controly, anchorx, anchory);
if (Math.abs(nextx-endx)<1e-10) {
// 画完曲线
break;
}
beginx<endx ? i++ : i--;
curx = nextx;
coscx = cosnx;
cccsc = cnnsn;
nextx = beginx+i*pi_6;
}
};
wave(0, 300, 100, 100, 0, 1000);
/////////////////
这位大虾最好,已经写好了注解,我就可以少点事情了.呵呵,忘记和板兰根了,等等
效果展示:

点击浏览该文件
源文件

点击浏览该文件

//////////////////////////////////////////////////////////////////////////////

下面我详细讲一讲一个线线函数的用法^_^
首先看看他们的定义:
MovieClip.lineStyle

可用*


Flash Player 6。

用法


myMovieClip.lineStyle ([thickness[, rgb[, alpha]]])

参数


thickness 一个整数,以磅为单位指示线条的粗细;有效值为 0 到 255。如果未指定数值,或者该参数为 undefined,则不绘制线条。如果传递的值小于 0,则 Flash 使用 0。数值 0 指示极细的粗细;最大粗细为 255。如果传递的值大于 255,则 Flash 解释程序使用 255。

rgb 线条的十六进制颜色值(例如,红色为 0xFF0000,蓝色为 0x0000FF,等等)。如果未指示该值,则 Flash 使用 0x000000(黑色)。

alpha 一个整数,指示线条颜色的 Alpha 值;有效值为 0 到 100。如果未指示该值,则 Flash 使用 100(纯色)。如果该值小于 0,则 Flash 使用 0。如果该值大于 100,则 Flash 使用 100。

返回


无。

说明


方法;指定一个线条样式,供 Flash 用于对 lineTo 和 curveTo 方法的后续调用,直到使用其他参数调用 lineStyle 为止。可以在绘制路径的中间调用 lineStyle 方法来为路径中的不同线条段指定不同的样式。

注意:调用 clear 会将 lineStyle 方法重置为 undefined。

////////////////////////////////////
MovieClip.moveTo

可用*


Flash Player 6。

用法


myMovieClip.moveTo (x, y)

参数


x 一个整数,指示相对于父影片剪辑的注册点的水平位置。

y 一个整数,指示相对于父影片剪辑的注册点的垂直位置。

返回


无。

说明


方法;将当前绘画位置移到 (x, y)。如果缺少任何一个参数,则此方法将失败,并且当前绘画位置不改变。

/////////////////////////////////////////////////////////////////////////
MovieClip.lineTo

可用*


Flash Player 6。

用法


myMovieClip.lineTo (x, y)

参数


x 一个整数,指示相对于父影片剪辑的注册点的水平位置。

y 一个整数,指示相对于父影片剪辑的注册点的垂直位置。

返回


无。

说明


方法;使用当前线条样式从当前绘画位置向 (x, y) 绘制线条;当前绘画位置随后被设置为 (x, y)。如果正在其中绘制的影片剪辑包含用 Flash 绘画工具创建的内容,则调用 lineTo 将在该内容下面进行绘制。如果在对 moveTo 方法进行任何调用之前调用了 lineTo 方法,则当前绘画位置默认为 (0, 0)。如果缺少任何一个参数,则此方法将失败,并且当前绘画位置不改变。

////////////////////////////////////////////////////////////////////////////////////
画一条直线(线段),置顶其两个断点就ok了
_root.createEmptyMovieClip("ban", 1);
ban.onEnterFrame = function() {
with (ban) {
lineStyle(5, 0x000000, 100);
moveTo(100, 100);
lineTo(200, 100);
}
};
***************************************
画等便三角形就复扎一点点,你要先计算计算---怎么计算?
3的平方根好像大概可能也许是1.732...........
_root.createEmptyMovieClip("ban", 1);
ban.onEnterFrame = function() {
with (ban) {
lineStyle(5, 0x000000, 100);
moveTo(100, 100);
lineTo(100, 200);
lineTo(13.4, 150);
lineTo(100,100);
}
};

**************************************************
然后是正方形,没有什么好讲的
_root.createEmptyMovieClip("ban",1);
ban.onEnterFrame=function(){
with(ban){
lineStyle(5,0x000000,100);
moveTo(100,100);
lineTo(200,100);
lineTo(200,200);
lineTo(100,200);
lineTo(100,100);
}
};
***********************************************************

然后用curvto绘制曲线,这个我不好讲,因为curvto绘图的依据原理我还不知道,
在闪吧as区发贴,还没有回答.
_root.createEmptyMovieClip("circle", 1);
with (circle) {
lineStyle(0, 0x000000, 100);
moveTo(100, 150);
curveTo(150, 150, 150, 100);
curveTo(150, 50, 100, 50);
curveTo(50, 50, 50, 100);
curveTo(50, 150, 100, 150);
}

****************************************************************
效果演示:

点击浏览该文件
源文件:

点击浏览该文件
//因该特别说明的一点就是,curto里面的点再画闭合曲线的时候应该末尾的点与moveto所指定的点重合.
//这个源文件我是直接重自己完整的文件里面粘贴一部分出来,所以有几个按钮的as是没有的.







下面想一下下用输入控制正多边形边数的问题
正多边形,我们可以用两种方法来达到,一个是定边长,一个是定外切圆半径
为了偷懒,我先画出了定边把它设置位电影夹子,然后用它来分别作为
定边长多边形的边和定外切圆半径的半径.
按此在新窗口浏览图片
按此在新窗口浏览图片
第一张图里面讲的是"定内径长"的情形,就是正多边形的外接圆的内径已经固定.
那么我们可以根据三角形的正弦和余弦来确定一个端点相对于与水平线的位置.
我们再开始的时候就画出(也可以用as来绘制,不用那么麻烦吧?要弄自己弄去)
水平的那条内径,这样有利于后面的确定计算公式.
第二张图里面讲的是定边长的情形,就是....就是定边长了,不会不懂吧?
为了节约时间,我们将边长转化为内径来求.
我们知道,正多边形每个端点到中心的距离是相同的(不要问我为什么,我不知道,直觉),
在边的数量和边长已经确定的情况下,我们可以确定内径的长度.也就是可以这样说:
对于已经固定边数和边长的正多边形,它的内径长是固定的.
于是我们利用余弦定理达到这个目的

那么反过来说,我们既然已经确定了其内径和边数,画出边的也就很简单了,举两个例子:
按此在新窗口浏览图片

那么反过来说,我们既然已经确定了其内径和边数,画出边的也就很简单了,举两个例子:
我们的OA边是事先确定好位置的(具体可以用一个复制函数复制一条线段,然后指定新线段的位置)
利用复制函数复制出四条新的新的线段,然后用rotation旋转角度(以72为单位)这样我们就确定了
端点和中心点链接的内径的位置了,只需要求出各点x,y就可以使用linestyle和lineto,moveto来
画出边线----当然,还要限制角度,这个我们在后面会将到.
十边形的情形差不多.
按此在新窗口浏览图片

为了避免后面的并非原创之嫌,我将第7楼的代码重新讲解一遍.

//创建一个新的电影夹子,命名为ban,放在1层
_root.createEmptyMovieClip("ban", 1);
//为电影夹子ban添加onclipevent事件
ban.onEnterFrame = function() {
with (ban) {
//指定线条样式为5磅粗,黑色,100可见度
lineStyle(5, 0x000000, 100);
//将起始画线点 移到(100,100)
moveTo(100, 100);
//画线到(200,100)
lineTo(200, 100);
}
};
//其实就是从(100,100)到(200,100)的一条线段
***************************************
画等便三角形就复扎一点点,你要先计算计算---怎么计算?
3的平方根好像大概可能也许是1.732...........
_root.createEmptyMovieClip("ban", 1);
ban.onEnterFrame = function() {
with (ban) {
lineStyle(5, 0x000000, 100);
moveTo(100, 100);
lineTo(100, 200);
lineTo(13.4, 150);
lineTo(100,100);
}
};
//等边三角形稍微复杂一点,我们事先要计算一下各个端点的位置
**************************************************
然后是正方形,没有什么好讲的
_root.createEmptyMovieClip("ban",1);
ban.onEnterFrame=function(){
with(ban){
lineStyle(5,0x000000,100);
moveTo(100,100);
lineTo(200,100);
lineTo(200,200);
lineTo(100,200);
lineTo(100,100);
}
};
***********************************************************

然后用curvto绘制曲线,这个我不好讲,因为curvto绘图的依据原理我还不知道,
在闪吧as区发贴,还没有回答.
_root.createEmptyMovieClip("circle", 1);
with (circle) {
lineStyle(0, 0x000000, 100);
moveTo(100, 150);
curveTo(150, 150, 150, 100);
curveTo(150, 50, 100, 50);
curveTo(50, 50, 50, 100);
curveTo(50, 150, 100, 150);
}


可能你会问,为什么一定要先画出内径,再画出边线?
呵呵,不过是为了大家好理解,你不画出内径,多边形一样能够出来.
楼下的,呵呵,其实很简单的,请你们从第9楼开始看,就不是那么复杂了.
我试图用先举例,再由浅入深的方法来讲解这个新的函数,
最开始的几贴看不懂没有关系,事实上我也自己编写不出前面四种方
法里面的三种.那些都是超强的人.
如果有人不明白"复制函数"请看我的这张贴里面的讲解:
http://bbs.flash8.net/cgi-bin/topic_show.cgi?id=69973&h=1&bpg=1&age=0 ;
当然,你不动也没有关系,因为,可以不用它,呵呵






下面继续:
我来讲一讲如何根据转动的角度来确定点的位置.
我们以上面的正五边形为例.
我们知道,如果转动的角度大于90度,
那么我们就因该重新考虑是否直接采用正弦和余弦.
OB的转动角度是小于90度的,那么我们可以直接用正弦余弦.

那么可以知道:if(a<90){......}
xB=xO+OB*cos(a);
yB=yO+OB*sin(a);
但是OC的转动角度大于了90度,那么又的地方我们就应该用减号而不是加号了.为了方便,
我们用180-a来将钝角转换为锐角,相应的,就需要在as里面添加if(a>90){......}的语句.
xC=xO-OC*cos(180-a);
yC=yO+OC*sin(180-a);
当转动的角度大于了180度,也就是if(a>180)
这时候我们就用(a-180),
xD=xO-OD*cos(a-180);
yD=yO-OD*sin(a-180);
当转动的角度大于了270度,怎么计算相信不需要我再说了吧.

//////////////////////////////////////////
至于具体怎么实现,情大家在仔细看了我的教程之后自己动手实践一下.
关键在于if语句的应用.

当然,这上面讲的是比较笨的办法,如果采用弧度的话,要简单一些,我在以后再讲(嘻嘻,我还没有做那)还有比上面的方法更笨的办法,那就是用下一边的起始点连接上一条线段的末端,转动一定的角度...................呵呵,自己想吧,我可不想,又难做又复杂!

呵呵,我今天说错了一点,数学离得久了一点儿.正弦和余弦不用限制范围久可以直接用了.
我做了一个,如下.
lengthNum是内径长度,lineNum是边的数目.
on (release) {
lengthNum = _root.lengthNum1;
lineNum = _root.lineNum1;
angle = 360/lineNum;
for (i=1; i<=lineNum; i++) {
dx = lengthNum*Math.cos(Math.PI*i*angle/180);
dy = lengthNum*Math.sin(Math.PI*i*angle/180);
hx = lengthNum*Math.cos(Math.PI*(i+1)*angle/180);
hy = lengthNum*Math.sin(Math.PI*(i+1)*angle/180);
createEmptyMovieClip("uu"+i, i);
with ("uu"+i) {
lineStyle(5, 0x000000, 100);
moveTo(300+dx, 300+dy);
lineTo(300+hx, 300+hy);
}
}
}
责任编辑:uufeng
上一篇: 拖动面板 下一篇: Flash MX Action画线方法(完结篇)
 
FLASH转GIF动画不失真的方法
AS轻松实现画多边形
Flash MX的坐标系统简介
as控制的颜色变化的渐进效果
Flash MX UI组件的初级应用
纯AS绘制圆形的一种方法
AS画任意多边形
《闪E》FLASH技术电子期刊第三期
神影无踪---廖添丁
JS to Flash
用Flash打造realplayer的
实例解析Flash绘制函数及_alpha应