Flash教程:数组知识概述(共7篇)由网友“shinenar”投稿提供,下面小编给大家整理后的Flash教程:数组知识概述,欢迎阅读与借鉴!
篇1:Flash教程:数组知识概述
知识点:
1、将字符串转换成数组split
2、将数组转换成字符串join
3、替换数组中的某元素和删除未定义的元素splice
4、添加元素到数组中push
5、数组中的数字按从小到大的顺序排列sort(Array.NUMERIC)
重点:
splice(m,n,x)
前一个参数m表示从m起,
中间一个参数表示删除n个元素
第三个参数是添加某些元素
zfc.text=“I will go to London”;
var arr:Array;
th_btn.visible=tj_btn.visible=sc_btn.visible=arr_zfc_btn.visible=false
zfc_arr_btn.addEventListener(MouseEvent.CLICK,zfc_arr);
function zfc_arr(e:MouseEvent):void {
arr=zfc.text.split(“ ”);//将字符串转换成数组
arr_txt.text=arr+“”;
zfc_arr_btn.mouseEnabled=false
th_btn.visible=true
th_btn.addEventListener(MouseEvent.CLICK,th);
}
function th(e:MouseEvent):void {
var _length:uint=arr.length;
for (var i:uint=0; i<_length; i++) {
if (arr[i]==“London”) {
arr.splice(i,1,“Shanghai”);//替换数组中的某元素
}
}
th_txt.text=arr+“”;
th_btn.mouseEnabled=false
tj_btn.visible=true
tj_btn.addEventListener(MouseEvent.CLICK,tj);
}
function tj(e:MouseEvent):void {
arr[8]=“in ”;//在数组中添加第9个元素,而原数组只有5个元素,则有3个未定义的元素
tj_txt.text=arr+“”;
tj_btn.mouseEnabled=false
sc_btn.visible=true
sc_btn.addEventListener(MouseEvent.CLICK,sc);
}
function sc(e:MouseEvent):void {
for (var j:uint=0; j
if (arr[j]==undefined) {//删除未定义的元素
arr.splice(j,1);
j--;
}
}
sc_txt.text=arr+“”;
sc_btn.mouseEnabled=false
arr_zfc_btn.visible=true
arr_zfc_btn.addEventListener(MouseEvent.CLICK,arr_zfc);
}
function arr_zfc(e:MouseEvent):void {
arr_zfc_txt.text=arr.join(“ ”);//数组转换成字符串
arr_zfc_btn.mouseEnabled=false
xh_btn.visible=true
}
//下面示例是从1-33任选6个不同的数
xh_btn.addEventListener(MouseEvent.CLICK,xh);
xh(null)//默认已经选号了一次
function xh(e:MouseEvent):void {
var num33:Array=[];
for (var m:uint=1; m<34; m++) {
num33.push(m);
}
var num6:Array=[];
for (var a:int = 0; a < 6; a++) {
num6.push(num33.splice((uint(Math.random*num33.length)),1));
if (num6[a]<10) {
num6[a]=“0”+num6[a];
}
num6.sort(Array.NUMERIC);
}
xh_txt.text=num6+“”;
}
更多内容进入:
精品学习网IT教育频道
篇2:Flash教程:鼠标绘制
知识点:
1、添加鼠标监听事件MouseEvent;
2、规定画布大小;
3、moveTo和lineTo;
4、绘制开始与结束判断,
代码:
var huabu:Sprite=new Sprite();
huabu.graphics.beginFill(0xFFFFFF);
huabu.graphics.drawRect(20,20,510,360);
huabu.graphics.endFill();
addChild(huabu);
var _drawing:Boolean;
var quxian:Sprite=new Sprite();
quxian.graphics.lineStyle( 2, 0xFF0000 );
huabu.addChild(quxian);
_drawing = false;
huabu.addEventListener( MouseEvent.MOUSE_DOWN, startDrawing );
huabu.addEventListener( MouseEvent.MOUSE_MOVE,moving);
huabu.addEventListener( MouseEvent.MOUSE_UP, stopDrawing );
stage.addEventListener(MouseEvent.MOUSE_UP,stopDrawing);
function startDrawing( event:MouseEvent ):void {
quxian.graphics.moveTo( mouseX, mouseY );
_drawing = true;
}
function moving( event:MouseEvent ):void {
if ( _drawing ) {
quxian.graphics.lineTo( mouseX, mouseY );
}
}
function stopDrawing( event:MouseEvent ):void {
_drawing = false;
}
(2):直线
知识点:
1、添加鼠标监听事件MouseEvent;
2、规定画布大小;
3、moveTo和lineTo;
4、绘制开始与结束判断。
难点:
绘制多条直线
代码:
var huabu:Sprite=new Sprite();
huabu.graphics.beginFill(0xFFFFFF);
huabu.graphics.drawRect(20,20,510,360);
huabu.graphics.endFill();
addChild(huabu);
var _drawing:Boolean=false;
var zhixian:Sprite=new Sprite();
huabu.addChild(zhixian);
var _color:Number=0xFF0000;
var zx:int=1;
var ys_x:Number;
var ys_y:Number;
huabu.addEventListener( MouseEvent.MOUSE_DOWN, startDrawing );
huabu.addEventListener( MouseEvent.MOUSE_MOVE,moving);
huabu.addEventListener( MouseEvent.MOUSE_UP, stopDrawing );
stage.addEventListener( MouseEvent.MOUSE_UP, stopDrawing );
function startDrawing( event:MouseEvent ):void {
ys_x=mouseX;
ys_y=mouseY;
_drawing = true;
}
function moving( event:MouseEvent ):void {
if (_drawing) {
huabu.removeChild(zhixian);
zhixian=new Sprite();
zhixian.graphics.lineStyle( zx, _color );
zhixian.graphics.moveTo(ys_x,ys_y);
zhixian.graphics.lineTo(mouseX,mouseY);
huabu.addChild(zhixian);
}
}
function stopDrawing( event:MouseEvent ):void {
zhixian=new Sprite();
huabu.addChild(zhixian);
//没有以上两句,只能画一条直线
_drawing = false;
}
(3):圆
知识点:
1、添加鼠标监听事件MouseEvent;
2、绘制过程中显示半径(两点间的距离Point.distance(坐标1,坐标2));
3、drawCircle、moveTo和lineTo;
4、绘制开始与结束判断。
难点:
绘制多个圆
代码:
var _drawing:Boolean;
var yuan:Sprite=new Sprite();
addChild(yuan);
var banjing:Sprite=new Sprite();
addChild(banjing);
var yuanxin_x:Number;
var yuanxin_y:Number;
var zuobiao1:Point;
var zuobiao2:Point;
var bj:Number;
_drawing = false;
stage.addEventListener( MouseEvent.MOUSE_DOWN, startDrawing );
stage.addEventListener( MouseEvent.MOUSE_MOVE,yd);
stage.addEventListener( MouseEvent.MOUSE_UP, stopDrawing );
function startDrawing( event:MouseEvent ):void {
yuanxin_x=mouseX;//鼠标按下的位置就是圆心的位置
yuanxin_y=mouseY;
_drawing = true;
}
function yd( event:MouseEvent ):void {
if ( _drawing ) {
zuobiao1 = new Point(yuanxin_x,yuanxin_y);
zuobiao2 = new Point(mouseX, mouseY);
bj= Point.distance(zuobiao1, zuobiao2);//显示两点之间的距离即为半径
removeChild(yuan);
yuan=new Sprite();
yuan.graphics.lineStyle( 2, 0xFF0000 );
yuan.graphics.drawCircle(yuanxin_x,yuanxin_y,bj);
addChild(yuan);
removeChild(banjing);
banjing=new Sprite();
banjing.graphics.lineStyle(2,0xFF0000,0.5);
banjing.graphics.moveTo(yuanxin_x,yuanxin_y);
banjing.graphics.lineTo(mouseX,mouseY);
addChild(banjing);
}
}
function stopDrawing( event:MouseEvent ):void {
removeChild(banjing);//绘制结束时半径线消失
banjing=new Sprite();//每次画圆过程中都显示半径
addChild(banjing);
yuan=new Sprite();//可绘制多个圆
addChild(yuan);
_drawing = false;
}
(4):椭圆
知识点:
1、添加鼠标监听事件MouseEvent和键盘监听事件KeyboardEvent;
2、椭圆的宽与高;
3、drawEllipse;
4、绘制开始与结束判断;
5、按下Shift键绘制正圆,
难点:
按下Shift键绘制正圆
代码:
var _drawing:Boolean=false;
var ellipse:Sprite=new Sprite();
addChild(ellipse);
var kaishi_x:Number;
var kaishi_y:Number;
var w:Number;
var h:Number;
var _max:Number;
stage.addEventListener( MouseEvent.MOUSE_DOWN, startDrawing );
stage.addEventListener( MouseEvent.MOUSE_MOVE,moving);
stage.addEventListener( MouseEvent.MOUSE_UP, stopDrawing );
function startDrawing( event:MouseEvent ):void {
kaishi_x=mouseX;
kaishi_y=mouseY;
_drawing = true;
}
function moving( event:MouseEvent ):void {
if (_drawing) {
w=mouseX-kaishi_x;
h=mouseY-kaishi_y;
removeChild(ellipse);
ellipse=new Sprite();
ellipse.graphics.lineStyle( 2, 0xFF0000 );
ellipse.graphics.drawEllipse(kaishi_x,kaishi_y,w,h);
addChild(ellipse);
}
}
function stopDrawing( event:MouseEvent ):void {
ellipse=new Sprite();
addChild(ellipse);
_drawing = false;
}
stage.focus=this;
stage.addEventListener(KeyboardEvent.KEY_DOWN, shift);
function shift(event:KeyboardEvent):void {
if (event.charCode==0) {
if (_drawing) {
w=mouseX-kaishi_x;
h=mouseY-kaishi_y;
_max=Math.max(Math.abs(w),Math.abs(h));
if (w<0 && h<0) {
w=-_max;
h=-_max;
}
if (w>0 && h>0) {
w=_max;
h=_max;
}
if (w<0 && h>0) {
w=-_max;
h=_max;
}
if (w>0 && h<0) {
w=_max;
h=-_max;
}
removeChild(ellipse);
ellipse=new Sprite();
ellipse.graphics.lineStyle( 2, 0xFF0000 );
ellipse.graphics.drawEllipse(kaishi_x,kaishi_y,w,h);
addChild(ellipse);
}
}
}
(5):矩形
知识点:
1、添加鼠标监听事件MouseEvent和键盘监听事件KeyboardEvent;
2、椭圆的宽与高;
3、drawRect;
4、绘制开始与结束判断;
5、按下Shift键绘制正方形。
难点:
按下Shift键绘制正方形
代码:
var _drawing:Boolean=false;
var _drawrect:Sprite=new Sprite();
addChild(_drawrect);
var yx_x:Number;
var yx_y:Number;
var w:Number;
var h:Number;
var _max:Number;
stage.addEventListener( MouseEvent.MOUSE_DOWN, startDrawing );
stage.addEventListener( MouseEvent.MOUSE_MOVE,moving);
stage.addEventListener( MouseEvent.MOUSE_UP, stopDrawing );
function startDrawing( event:MouseEvent ):void {
yx_x=mouseX;
yx_y=mouseY;
_drawing = true;
}
function moving( event:MouseEvent ):void {
if (_drawing) {
w=mouseX-yx_x;
h=mouseY-yx_y;
removeChild(_drawrect);
_drawrect=new Sprite();
_drawrect.graphics.lineStyle( 2, 0xFF0000 );
_drawrect.graphics.drawRect(yx_x,yx_y,w,h);
addChild(_drawrect);
}
}
function stopDrawing( event:MouseEvent ):void {
_drawrect=new Sprite();
addChild(_drawrect);
_drawing = false;
}
stage.focus=this;
stage.addEventListener(KeyboardEvent.KEY_DOWN, shift);
function shift(event:KeyboardEvent):void {
if (event.charCode==0) {
if (_drawing) {
_max=Math.max(Math.abs(w),Math.abs(h));
if (w<0 && h<0) {
w=-_max;
h=-_max;
}
if (w>0 && h>0) {
w=_max;
h=_max;
}
if (w<0 && h>0) {
w=-_max;
h=_max;
}
if (w>0 && h<0) {
w=_max;
h=-_max;
}
removeChild(_drawrect);
_drawrect=new Sprite();
_drawrect.graphics.lineStyle( 2, 0xFF0000 );
_drawrect.graphics.drawRect(yx_x,yx_y,w,h);
addChild(_drawrect);
}
}
}
更多内容进入:
精品学习网IT教育频道
篇3:Flash教程三维引擎初探
本文将介绍的是一个简单的实时3D引擎,并以此向大家阐明一种用Action Script在Flash二维的世界里表现三维对象的方法,先看看一个线描的简单实例,这是一个三棱锥绕自己的一条棱旋转的动画。
基本原理:我们所生活的世界是一个由x,y,z轴(也就是长宽高)组成的三维世界,要在一个二维平面上表现出三维的信息,我们首先必须要去掉三个坐标轴中的一个,z轴(表示物体深度的轴)。此外,我们还必须要选择一个视点,也就是代表观察者眼睛的一个点,和一个用于投影三维物体所有点的视平面,也就是我们所看见的那个面。然后,从三维物体上每个点到视点之间连线和视平面的交点就是该点在视平面上所应在位置。看了上面的一长串话是否有点头晕?没关系,请看看下面的那张图。
从图中我们可以看出当视点和物体AB位置不变,如果视平面S离物体AB越近,那么物体AB在视平面S上的投影A'B'(即我们所看到的对象)就越大。
实例:知道大致原理后,我们来看个三棱锥的例子。为了简单起见,我们假设视点,也就是眼睛的位置,是处于z轴之上的;另外,视平面S平行于x,y轴。
预备
新建一个Flash文件,并新建两个层,分别命名为actions和modal。新建一个图形元件(Graphic Symbol)并将之命名为line,在此元件中画一条沿45度角斜向右下方的直线并将之长宽皆设为100。
在actions层中插入9帧空白关键帧,并依次命名为modal info,init,start,loop,drawline,draw,rotx,roty和rotz。在modal层上插入4帧,然后将line元件从Library中拖到舞台上并将此实例命名为baseline。
一、模型定义
使用某种编码方式将我们所要进行操作的三维对象表示出来的就是本步骤要做的。在这里,我们只建立简单的框架三维模型,所以只定义模型顶点以及点与点之间的线就够了。
1.1 定义点
在三维坐标系中的每个点都对应维一的一组x,y,z坐标量。因此,我们可以建立一个变量,比如叫points,并使用下面的编码方式来存放各点的坐标值:
“
”
其中
代表第n个点的坐标,每个坐标值以三位数字来表示,即,12编码为012;1编码为001;点(33,1,0)编码为(033,001,000)。
然后,为了让每组坐标看起来清晰点,将每个点的坐标之间以一个字符R(其实随便什么都可以)来分隔。此外,还要定义一个变量,比如说叫totalpoints,来确定总的点数。
1.2 定义线
很早以前老师就告诉我们两点确定一条直线这个道理。根据这个老道理,我们只要确定两个端点的坐标值便能确定一条线段。所以,我们可以生成一个变量,比如叫lines,并使用跟上面定义点相类似的编码方式来存放各条线的定义:
“
”
其中
代表第n条线段的两个端点坐标,每个端点以两位数字来表示。例如,从顶点1到顶点5的线段就被编码为0105。这里你可能会发现,这个简易3D引擎只能最多定义99个点。如果你需要添加点数的话其实也很简单,只要增加用以表示每个端点的数字的位数即可。
同样的,你得建立一个用来确定总线段数的变量,比如叫totallines。
1.3 其它的变量
定义完了点和线,我们还得告诉引擎眼睛的位置(比如说eyez)以及视平面所处的深度(zorder)。视点(eyez)离物体越远,物体的透视效果就会越差。
1.4 构建三棱锥
用于构建模型的变量差不多都介绍完了,下面就在modal info帧中输入以下这段定义一个三棱锥模型的代码:
totalpoints=4;//四个顶点
points=“010,010,000R090,000,000R090,090,090R000,090,000”;//四个顶点的坐标
totallines=6;//六条边
lines=“0102R0103R0104R0203R0204R0304”;//六条边的定义
eyez=-500;//视点的位置
zorder=100;//视平面深度
二、构建引擎
这一步是整个程序的核心,完成了引擎差不多就等于完成了全部。
2.1 初始化
在开始真正的引擎前我们先来做一些初始化的工作——将所定义模型的信息转存到一个个单独的变量中。在init帧中输入以下代码:
setProperty (“/baseline”, _x, 1000);//隐藏原来的那条线
//下面的循环转存所有点的信息
for (i=1; i<=totalpoints; i++) {
set (“x” add i, substring(points, Number((i-1)*12+1), 3));
set (“y” add i, substring(points, Number((i-1)*12+5), 3));
set (“z” add i, substring(points, Number((i-1)*12+9), 3));
}
//下面的循环转存所有线的信息
for (i=1; i<=totallines;i++) {
set (“pt1” add i, substring(lines, Number((i-1)*5+1), 2));
set (“pt2” add i, substring(lines, Number((i-1)*5+3), 2));
}
//下面两个变量分别表示显示中心点的x和y
centerx=190;
centery=215;
2.2 创建基本循环
完成了初始化,下面我们来建立程序中最基本的循环,
选中loop帧,并在其中输入:
gotoAndPlay (“start”);
2.3 绘制模型
绘制模型的过程可分为两个部分,第一部分将三维物体的各点坐标值转换为投影到视平面S上的相应二维坐标;第二部分根据转换完毕的二维坐标在视平面S上绘制出图像。在这个例子里我们在帧draw里面进行三维坐标的二维化,然后使用帧drawline来进行绘制工作。所以,在帧draw里输入以下的代码:
//下面的循环根据公式进行三维坐标的二维化
for (i=1; i<=totalpoints; i++) {
u = (zorder-eyez)/(eval(“z” add i)-eyez);//二维化公式
if (i<=9) {
set (“2Dx0” add i, u*eval(“x” add i)+centerx);
set (“2Dy0” add i, u*eval(“y” add i)+centery);
} else {
set (“2Dx” add i, u*eval(“x” add i)+centerx);
set (“2Dy” add i, u*eval(“y” add i)+centery);
}
}
//下面的循环负责复制线段并将之显示出来
for(i=1;i<=totallines;i++){
duplicateMovieClip(“/baseline”,“line” add i,i);
call(“drawline”);
}
在帧drawline里输入以下的代码:
pt1 = eval(“pt1” add i);
pt2 = eval(“pt2” add i);
setProperty (“line” add i, _x, eval(“2Dx” add pt1));
setProperty (“line” add i, _y, eval(“2Dy” add pt1));
setProperty (“line” add i, _xscale, eval(“2Dx” add pt2) - eval(“2Dx” add pt1));
setProperty (“line” add i, _yscale, eval(“2Dy” add pt2) - eval(“2Dy” add pt1));
至此绘制模型的工作大致就做完了,在start帧中输入:
call(“draw”);
按Ctrl+Enter后就可以看到你所定义的模型的模样了。
2.4 旋转
旋转其实也很简单,只要将坐标根据不同旋转角度重新映射一次就可以了,下面是一组用于旋转计算的公式:
沿x轴旋转:
沿y轴旋转:
沿z轴旋转:
由于篇幅有限,这里就只介绍一种旋转方式——沿x轴旋转。
根据上面的这些公式,我们还需要设置一些变量来满足要求。在init帧中追加以下的代码:
basecos=0.9848; //cos10的值
basesin=0.1736; //sin10的值
cos=basecos;
sin=basesin;
axis=“x”;//沿哪个轴旋转,这里是x也就是说沿x轴旋转
在rotx中输入如下的代码:
//根据不同的角度值重新计算二维坐标
for (i=1; i<=totalpoints; i++) {
set (“tmp”, (sin*eval(“y” add i))+(cos*eval(“z” add i)));
set (“y” add i, (cos*eval(“y” add i))-(sin*eval(“z” add i)));
set (“z” add i, tmp);
}
接下来只要在start帧中call(“draw”);的上面插入一句
call(“rot” add axis);//根据axis的值调用不同类型的旋转
这样,整个引擎基本上就可以算是完工了。另外两帧roty 和rotz大家只要参照相应的公式填一下应该是没什么大问题的。
如开头所说,这个引擎在功能上其实是相当简陋的,甚至是有相当多BUG的。但本文只是想抛砖引玉,向各位展示一种思路,引擎的完善与实用化留待各位有兴趣的朋友自己慢慢研究了。
篇4:Flash教程:随机生成树冠
用程序随机生成树冠,说明一下,元件“树”里的dp值控制树枝生长的深度,越高的话则分的越多,但请注意,dp超过13就有可能造成FLASH运行缓慢,
我解释一些代码的用处,以“右叉”的最后一帧代码来解释。
stop;
if (dp>0) { //dp用来控制树枝的生长,当dp<0的时候,树枝将不在分裂生长。
//以下是正上方新树枝的代码
k=random(4)+1; //k用来选择树形,分别是直形,左分形,右分形和中分行。
_parent.attachMovie(“sz_0”+k,“sz”+_parent.dp,_parent.dp); //生成一个新的树枝。
lik=_parent[“sz”+_parent.dp]; //用LIK锁定这个树枝,方便以后控制
rp=this._rotation+0; //rp是新的树枝的根坐标(黄点)相对于现在这个树枝根坐标(蓝点)的角度,此数值影响到将要新生成的新树枝的坐标。这里是以极坐标的角度来考虑的,因为该树枝的第一个点在正上方,所以修正值是0。
lp=62; //在rp这个方向上,新树枝根坐标的距离。
_parent.dp++; //深度控制,大家可以不用考虑
lik._x=this._x+lp*Math.sin(rp/180*Math.PI)*scal/100;
lik._y=this._y-lp*Math.cos(rp/180*Math.PI)*scal/100;
// 以上算式计算的是新树枝的根坐标,具体意思请参考极坐标和直角坐标换算的方式,
里面的scal是本树枝的缩放度。它会对坐标产生影响。
lik.scal=this.scal*_parent.jian; //新树枝的缩放度要比当前树枝的缩放度小一些
lik._xscale=lik.scal;
lik._yscale=lik.scal;
lik._rotation=rp+random(30)-15;; //新树枝的角度是当前树枝的角度向左右各15度随机摆动。(就是-15到+15度)
lik.dp=this.dp-1; //新树枝的生长度-1;
//以下是右侧新树枝的代码
k=random(4)+1;
_parent.attachMovie(“sz_0”+k,“sz”+_parent.dp,_parent.dp);
lik=_parent[“sz”+_parent.dp];
rp=this._rotation+20; //注意20度角度是这个新树枝的极坐标角度。
lp=52; //52是距离
_parent.dp++;
lik._x=this._x+lp*Math.sin(rp/180*Math.PI)*scal/100;
lik._y=this._y-lp*Math.cos(rp/180*Math.PI)*scal/100;
lik.scal=this.scal*_parent.jian;
lik._xscale=lik.scal;
lik._yscale=lik.scal;
lik._rotation=rp+random(30)+5;; //角度会向右偏一些,所以是当前角度增加5到35之间
lik.dp=this.dp-1;
}
当然管理员也提到了这是分形。
更多内容进入:
精品学习网IT教育频道
篇5:从头开始学习FLASH 3D教程
教程
效果演示:(用鼠标直接拖拽下面的物体)
点击这里下载源文件
大家都知道三维的点都有3个坐标,但FLASH只是有二维的坐标,所以要在FLASH里实现“三维”的效果,就需要对点的坐标进行转化,简单的说,就是怎么把三维坐标转换成二维坐标,(其实,这并不是真正的三维,而是一种视觉欺骗,看上去像三维的就这么回事。所以上面三维带引号。)
一、三维坐标系转化成二维坐标系
(1)、坐标的转换
flash中场景左上角为(0,0),而在数学中是场景中心为(0,0),怎样把它转成数学中的坐标系呢?
1.FLASH里的坐标视图
x=Stage.width/2; // Stage.width是场景的宽;
y=Stage.height/2; // Stage.height是场景的高;
这样就把原坐标的原点移动了,场景的中心点,不过,Y轴还是向下,为正的。(这在后面做旋转时要注意的。)
(2)、角度的转换
flash中Math函数里的参数都要用到弧度,所以角度与弧度之间的转换是需要知道的。
在flash as中,我们可以通过这样的表达式来进行转换:
hudu=jiaodu*Math.PI/180; / /把角度转换为弧度,公式为:弧度=角度 *3.14/180,3.14为pai
jiaodu=hudu*180/Math.PI; / /把弧度转换为角度,公式为:角度=弧度*180/3.14,3.14为pai
(if (jiaodu<0) { jiaodu = jiaodu+360; }/* 转换后的角度的范围从-180到180, 数学中的角度从0到360,所以小于0时加上360 */)
2、flash中的三维坐标系
如图3,z轴表示一个物体离屏幕的远近,当物体的z轴位置增加时,物体朝远离屏幕的方向运动,当物体的z值减小时,物体朝接近屏幕的方向运动。
图3:三维坐标系
图4:二维与三维的点的关系
3、三维坐标转换成二维坐标
如图4,已知一个点(x,y,z),利用三角形相似的原理,可以得出下列结论:
d/(d+z)=y1/y,推出:y1=d*y/(d+z),可在二维平面上来表现空间上的点的位置。进一步把它简化。提出因子d/(d+z),用ratio(比率)表示,这个公式就变为
ratio=d/(d+z);
y1=ratio*y;同理可推出
x1=ratio*x;
二、控制物体的属性(大小,层次,透明度等)
1、控制mc的大小
在三维坐标中,当z值增大,也就是远离屏幕时,物体应越小,反之越大。
我们可以用上满的ratio,当z增加时,ratio减少,因为在ratio中,z是作为分母的。反之,当z减少时,ratio增加。所以可用ratio来控制mc的大小。如下:
mc1._xscale=mc._xscale*ratio;
mc1._yscale=mc._yscale*ratio;
2、控制mc的层次
z值最大,物体应在最底层,最小,在最上层,
所以mc的层次可以有z组成,可以用很大的数减z,也可以让z除以负数,等等,这里方法比较灵活,也是做”三维”效果的关键,主要要在调试中确定适合设计的方法。flash中,设置mc的层次用swapDepths,如下:
mc.swapDepths(1000-z);//设置mc的层次
mc.swapDepths(z/-4);
3、控制mc的透明度
远处的物体看上去模糊些,近处的物体清晰些,在flash中,可用_alpha来控制,方法和控制大小类似,不在介绍原理。如下:
mc._alpha=100*ratio;
4、控制mc的角度(旋转)
这一步最难,也最好的东东。学习以后,你将能制作出非常cool的效果
旋转有三种,x旋转:坐标x不变,y旋转:y不变,z旋转:z不变,我们先来推导z旋转。
如下图:从点(x,y,0)转到(x1.y1.0),求点(x1.y1.0)
利用数学中的正弦、余弦公式得出
x1=r*cos(a+b),而cos(a+b)=sina*cosb+cosa*sinb
推出:x1=r(cosa*cosb-sina*sinb)
又因为x=r*cosa,y=r*sina
所以x1=x*cosb-y*sinb
同样推出:y1=y*cosb+x*sinb
这就是z旋转的公式。用同样的方法可推出x旋转,y旋转的公式。总结如下:
给定点:(x,y,z)
绕x轴旋转后的点(x1,y1,z1)
绕y轴旋转后的点(x2,y2,z2)
绕z轴旋转后的点(x3,y3,z3)
x旋转(x不变)
x1=x
y1=y*cosb-z*sinb
z1=z*cosb+y*sinb
注:x旋转要注意,在FLASH中x1=x
y1=y*cosb+z*sinb
z1=z*cosb-y*sinb
是先加后减,因为FLASH里的Y轴是反的,箭头向下的。
y旋转(y不变)
x2=x*cosb-z1*sinb
y2=y1
z2=z1*cosb+x*sinb
z旋转(z不变)
x3=x2*cosb-y1*sinb
y3=y1*cosb+x2*sinb
z3=z2
从以上公式可看出,在flash要实现旋转,先要求x轴的旋转点,再求y轴的旋转点,最后再求出z轴的旋转点。最后我们来一个x旋转的应用
三、制作x轴旋转的正方体
1、在场景中画一小球,并按F8转换为mc,实例命名为qiu。
2、增加一层,命名为as,接下去我们来写as,如下:
_root.onLoad = function() {
shumu = 8;
// 定义复制小球的数目
qiu._x = 6000;
// 让原始小球消失
for (var i = 0; i duplicateMovieClip(“qiu”, “qiu”+i, i); } // 复制小球,作为正方体的八个顶点 qiu_pos_x = new Array(100, 0, 0, 100, 100, 0, 0, 100); qiu_pos_y = new Array(100, 100, 100, 100, 0, 0, 0, 0); qiu_pos_z = new Array(50, 50, -50, -50, 50, 50, -50, -50); // 从三维坐标中取正方体的8个顶点的坐标,保存在数组中 D = 200; // 观察者与屏幕的距离 hutu = 0.001; // 控制旋转的速度 b = hutu*180/Math.PI; // 角、弧度的转换 }; _root.onEnterFrame. = function() { for (var i = 0; i x1 = qiu_pos_x[i]; y1 = qiu_pos_y[i]*Math.cos(b)-qiu_pos_z[i]*Math.sin(b); z1 = qiu_pos_z[i]*Math.cos(b)+qiu_pos_y[i]*Math.sin(b); // 按公式计算 qiu_pos_x[i] = x1; qiu_pos_y[i] = y1; qiu_pos_z[i] = z1; // 更新数组元素 ratio = D/(D+z1); perspective_x = x1*ratio; perspective_y = y1*ratio; // 按公式计算 _root[“qiu”+i]._x = 275+perspective_x; _root[“qiu”+i]._y = 200-perspective_y; / 设置球的坐标 _root[“qiu”+i]._xscale = _root[“qiu”+i]._yscale=50*ratio; // 球的大小 _root[“qiu”+i].swapDepths(10000-qiu_pos_z[i]); // 球的层次 _root[“qiu”+i]._alpha=100*ratio;//设置透明度 } }; 3、按CTRL+Enter测试,一个简单的3D旋转就形成了。 (至此为止,上面部分的教程很大程度上是参考《flash 3D 基础教程》(作者:zjs35 文章来源:flashempire 更新时间:-4-7)的,本人只在上面做了微小部分的修改,主要因为这篇对FLASH_3D效果的基础理论确实写的很好。修改的部分,是本人在学习之后,自己在实践练习中发现的一些需要注意的地方。) 接下来将为大家解析一篇某人大虾写的立方体旋转的FLASH_AS,这位大虾是用纯AS写的,只要把代码全部复制到第一桢就可以了。我将做详细的解析!!! //先给各项赋值,为后面的编辑作做准备 plane = [0, [0, 1, 2, 3, 4], [0, 5, 6, 7, 8], [0, 1, 2, 6, 5], [0, 2, 3, 7, 6], [0, 4, 3, 7, 8], [0, 1, 4, 8, 5]]; //给立方体的8个点都标上数,这里定义的数组是立方体的6个面,每个面上4个点,上面的数字就是哪四个点组成一个面,每组前面多个0,是为了下面做循环调用是方便,循环可以从i=1开始。大家自己可以根据上面的数组。画出它在三维坐标中的立体图形。另,第一“0“,其实是[0,0,0,0,0]。 dx = [0, 1, -1, -1, 1, 1, -1, -1, 1]; //这里是给8个点在三维坐标定义数组,竖着看,没一行就是一个点坐标的(x,y,z) ,另没组前面多个0,是为了下面做循环调用是方便,循环可以从i=1开始。 dy = [0, 1, 1, 1, 1, -1, -1, -1, -1]; // dz = [0, 1, 1, -1, -1, 1, 1, -1, -1]; // colour=0x4499FF //这里定义的是立方体的颜色,其实,要6个面,每个面的颜色不同,就把这个colour定义成数组就可以了。同样前面加个0,也是上面的理由。 //colour=[0,0x4499FF,0x6F13EC,0xF1F00E,0x6CE31C,0x26D9A3,0x808080]; trans = Math.PI/180; //下面的弧度和角度的转换用 cube_width = 100; //用于设定立方体的边的长度 d = 400; //// 观察者与屏幕的距离 num_planes = plane.length-1; //num_planes=6 num_nodes = dx.length-1; //num_nodes=8 num_nodes_per_plane = plane[1].length-1;//num_nodes_per_plane=4 xz_angle_inc = 0; //下面这4个定义对用鼠标控制旋转的速度有关, yz_angle_inc = 0; angle_inc_factor = .1; angle_dec_factor = .9; o_x = Stage.width/2; //把坐标原点移到屏幕中心 o_y = Stage.height/2; node = new Array(); //定义新数组 p_node = new Array(); //边长调整... 主要是求出8个点,在设定边长,情况下的坐标 for (i=1; i<=num_nodes; i++) { node[i] = new Object(); node[i].x = dx[i]*(cube_width/2); node[i].y = dy[i]*(cube_width/2); node[i].z = dz[i]*(cube_width/2); } for (i=1; i<=num_planes; i++) { //建立6个空白的影片剪辑,主要用于,每天影片剪辑,画一个立方体的面, _root.createEmptyMovieClip(“plane”+i, i); } //版面的调整 下面的_root.onEnterFrame. 会调用这里进行画立方体 //对这里不理解的,看附录一的代码! function create_planes() { for (var i = 1; i<=num_planes; i++) { depth = 0; //设定深度初始值 mc = _root[“plane”+i]; //每个影片剪辑画一个立方体的一个面 mc.clear(); //清除上次画的面,不用这句语句,可以看到面的连续旋转的会是什么轨迹,程序是怎么画的。不过,很难看。 mc.beginFill(colour, 100); //设置立方体面的颜色,colour可以变数组colour[i],这样每个面可以画,不同的颜色。 mc.lineStyle(3,0xFF0000,100);//设置立方体的棱的颜色 mc.moveTo(p_node[plane[i][1]].x, p_node[plane[i][1]].y);//这里设定每个正方形面,开始画时的启始点。 for (j=num_nodes_per_plane; j>=1; j--) { //这里是连续读取4个点,画好一个正方形 mc.lineTo(p_node[plane[i][j]].x, p_node[plane[i][j]].y); depth += node[plane[i][j]].z; //求每个面上4点旋转后,4个点的深度变化,并相加 } depth /= -num_nodes_per_plane;//注意除以负数,这样符合,FLASH的深度变化的远近情况 mc.swapDepths(depth); //有点的深度变化,来控制面的层次变化,如果没有这句,可以看到一个立方体在旋转是6个面的层次混乱。 amount = depth/50*100+15;//用深度变化,在传值,这个参数主要用于下面的语句,下面的语句,用于立方体在旋转时,面的亮度的调整,符合一定的光照效果。 new Color(mc).setTransform({ra:amount, ga:amount, ba:amount}); //这句语句可以查看FLASH_AS语法参考,可以找到的。主要是对色彩的设置。 } } //鼠标激发 _root.onMouseDown = function() { mouse_down = true; }; _root.onMouseUp = function() { mouse_down = false; }; _root.onEnterFrame. = function() { if (mouse_down) { //判断,鼠标情况,对鼠标移动距离的相加,如果,没有“+=”而用“=”,这样鼠标每点一次,图象就跳回初始状态。可以自己实验看下效果,进行对比。 xz_angle_inc += (_xmouse-old_mx)*angle_inc_factor; yz_angle_inc += (_ymouse-old_my)*angle_inc_factor; } for (i=1; i<=num_nodes; i++) { sin_xz = Math.sin(xz_angle_inc*trans); //对弧度与角度的转化公式。 cos_xz = Math.cos(xz_angle_inc*trans); sin_yz = Math.sin(yz_angle_inc*trans); cos_yz = Math.cos(yz_angle_inc*trans); rx1 = cos_xz*node[i].x-sin_xz*node[i].z; //这里就是上面的坐标转换公式里的,先按Y轴旋转,再按X轴旋转。 ry1 = node[i].y; rz1 = cos_xz*node[i].z+sin_xz*node[i].x; rx2 = rx1; ry2 = cos_yz*ry1+sin_yz*rz1; rz2 = cos_yz*rz1-sin_yz*ry1; node[i].x = rx2; //这里是把每个旋转后,得到的先的坐标保存在变量里 node[i].y = ry2; node[i].z = rz2; p_ratio = d/(d+node[i].z); //这个是上面d/(d+z) p_node[i] = new Object(); p_node[i].x = o_x+node[i].x*p_ratio; //确定在屏幕上点的位置 p_node[i].y = o_y-node[i].y*p_ratio; } xz_angle_inc *= angle_dec_factor; //这个加速鼠标控制时的旋转速度 yz_angle_inc *= angle_dec_factor; old_mx = _xmouse; //得到影片开始时的鼠标坐标 old_my = _ymouse; create_planes(); //调用上面的函数,画出立方体 }; //点评:本人只所以选择这个例子进行解析,主要是因为画立方体,是很常见的例子,也是3D里的一个基本的画法。另,这个例子的代码是很精练,简洁,再加上代码的前部分定义的一些值,利于以后做其他项目的开发,可以把这个程序改成一个类,适合自身以后,对画立方体时调用。同时,可以在这个程序基础上做进一步开发!比如,将好几个立方体叠起来,把图片放在立方体的面上,做一些旋转立体按钮等等,都是可以的。 //附录一: /*function create_planes(){ depth=0; plane1.clear(); plane1.beginFill(0xAB548B,100); plane1.lineStyle(3,0xFF0000,100); plane1.moveTo(p_node[5].x,p_node[5].y); plane1.lineTo(p_node[8].x,p_node[8].y); plane1.lineTo(p_node[7].x,p_node[7].y); plane1.lineTo(p_node[6].x,p_node[6].y); plane1.lineTo(p_node[5].x,p_node[5].y); depth=node[8].z+node[7].z+node[6].z+node[5].z; depth=depth/(-4); plane1.swapDepths(depth); amount=depth/50*100+15; //new Color(plane1).setTransform({ra:amount,ga:amount,ba:amount,aa:amount}); new Color(plane1).setTransform({ra:amount,ga:amount,ba:amount}); depth=0; plane2.clear(); plane2.beginFill(0x808080,100); plane2.lineStyle(3,0xFF0000,100); plane2.moveTo(p_node[1].x,p_node[1].y); plane2.lineTo(p_node[2].x,p_node[2].y); plane2.lineTo(p_node[3].x,p_node[3].y); plane2.lineTo(p_node[4].x,p_node[4].y); plane2.lineTo(p_node[1].x,p_node[1].y); depth=depth+node[4].z+node[3].z+node[2].z+node[1].z; depth=depth/(-4); plane2.swapDepths(depth); amount=depth/50*100+15; new Color(plane2).setTransform({ra:amount,ga:amount,ba:amount}); depth=0; plane3.clear(); plane3.beginFill(0x8A0FF0,100); plane3.lineStyle(3,0xFF0000,100); plane3.moveTo(p_node[1].x,p_node[1].y); plane3.lineTo(p_node[2].x,p_node[2].y); plane3.lineTo(p_node[6].x,p_node[6].y); plane3.lineTo(p_node[5].x,p_node[5].y); plane3.lineTo(p_node[1].x,p_node[1].y); depth=depth+node[1].z+node[2].z+node[6].z+node[5].z; depth=depth/(-4); plane3.swapDepths(depth); amount=depth/50*100+15; new Color(plane3).setTransform({ra:amount,ga:amount,ba:amount}); depth=0; plane4.clear(); plane4.beginFill(0xE61A48,100); plane4.lineStyle(3,0xFF0000,100); plane4.moveTo(p_node[2].x,p_node[2].y); plane4.lineTo(p_node[3].x,p_node[3].y); plane4.lineTo(p_node[7].x,p_node[7].y); plane4.lineTo(p_node[6].x,p_node[6].y); plane4.lineTo(p_node[2].x,p_node[2].y); depth=depth+node[2].z+node[3].z+node[7].z+node[6].z; depth=depth/(-4); plane4.swapDepths(depth); amount=depth/50*100+15; new Color(plane4).setTransform({ra:amount,ga:amount,ba:amount}); depth=0; plane5.clear(); plane5.beginFill(0x49B667,100); plane5.lineStyle(3,0xFF0000,100); plane5.moveTo(p_node[4].x,p_node[4].y); plane5.lineTo(p_node[3].x,p_node[3].y); plane5.lineTo(p_node[7].x,p_node[7].y); plane5.lineTo(p_node[8].x,p_node[8].y); plane5.lineTo(p_node[4].x,p_node[4].y); depth=depth+node[4].z+node[3].z+node[7].z+node[8].z; depth=depth/(-4); plane5.swapDepths(depth); amount=depth/50*100+15; new Color(plane5).setTransform({ra:amount,ga:amount,ba:amount}); depth=0; plane6.clear(); plane6.beginFill(0xDEB321,100); plane6.lineStyle(3,0xFF0000,100); plane6.moveTo(p_node[1].x,p_node[1].y); plane6.lineTo(p_node[5].x,p_node[5].y); plane6.lineTo(p_node[8].x,p_node[8].y); plane6.lineTo(p_node[4].x,p_node[4].y); plane6.lineTo(p_node[1].x,p_node[1].y); depth=depth+node[1].z+node[5].z+node[8].z+node[4].z; depth=depth/(-4); plane6.swapDepths(depth); amount=depth/50*100+15; new Color(plane6).setTransform({ra:amount,ga:amount,ba:amount}); }*/
篇6:Flash AS基础精典教程
教程
这次给大家带来MOOCK在世界性FLASH大会:FF2K1大会上的演说,要说到Action的权威,当然要数MOOCK,他写的ASDG(一本书)是可以和FLASH自带的AS字典相提并论的宝贝,虽然他是这样一个高高手,但是他的这个演讲却是非常的浅显,如果你某处读起来觉得难,那也一定是chocobo翻译得不好。(有些地方实在是太浅,我受不了就改了 )
这篇文章预算的演讲时间很长,所以读起来也会觉得较长,你可以分开来读。
还有,本文是关于FLASH5的AS的,毕竟FLASH4的AS已经淘汰。
第一章:由O开始
为了示范,MOOCK将会做一个多选题问答的动画来做为例子。
这个例子以4种不同版本的方法来实现。
对于用户来说,4种版本使用起来将没有区别,只是对于我们开发者来说,研究的就是如何改进这些FLASH代码的结构与组织。
改进的重点在于:
*更便易的维护
*更便易的扩展
*更快捷的建设
要牢记的是,学习编程是一个过程(process)而不是一个事件(event)。如果你第一次学习到的时候不能照着完成也不必担心。接下来,MOOCK说到为了照顾没有多少编程经验的菜鸟,会由最最最简单的开始。
关于计算机语言:
编程语言是用来发信息给电脑,从电脑接受信息的,编程语言也有词汇表和文法,如人类的语言类似,通过编程语言我们可以告诉电脑去做什么,也可以从他那获得信息.
关于语法和逻辑
学习编程的思想比学习一种语言的语法重要.假设FLASH是懂我们语言的单词的,我们对FLASH说:“Flash, 让一个球在屏幕里面弹来弹去吧”。FLASH会什么都做不了,FLASH要我们用他的世界懂的东西,例如:movie clips, buttons, frames,来描述它要做的事,那我们再说一次:“Flash, 让一个名字叫ball_one的movie clip在屏幕里面弹来弹去吧”,我们已经用MC这个FLASH懂的东西来描述了,但FLASH还是什么都不做,因为它需要更多的信息:
*这个球有多大
*它放在哪里?
*一开始它首先往哪个方向运动?
*它初始的速度是多少
*它在屏幕的那一个范围之内弹来弹去呢?
*弹来弹去要持续多久呢?
看来我们需要有逻辑结构地告诉FLASH它应该怎么去做
1、一个球指的是一个叫ball_one的圆形MC,直径50像素
2、还有一个方形MC叫square,边长300像素
3、将ball_one放在square上某处
4、以一个随机的角度,75像素每秒的速度开始移动ball_one
5、如果ball_one接触到square的某边,就弹回
6、一直不停地运动下去,知道我们让它停
如果FLASH真的懂我们语言的单词,他应该知道如何开始做了
总结一下关键点:
无论是使用什么语言,编程思想的艺术都在于用如何将逻辑步骤列出
在你开始将要做的事用计算机语言描述之前,用我们人类的语言描述一次会很有帮助
即使你将他们翻译成任何的计算机语言,他们的逻辑步骤应该是一样的
电脑不懂用假设完成去你的想法,他们没有思考能力(chocobo:就是你要把要求完全无遗漏地写出来让它运行)
第二章:基础
首先了解如何在FLASH输入程序
在FLASH菜单Window里面Actions可打开ACTION面板,ACTION面板分右面的脚本窗,和左面的工具窗
脚本窗就是放脚本的地方,而工具窗用于快速地输入各种ACTION,运算符,函数,属性,对象
MOOCK建议大家使用专家模式,在FLASH菜单的Edit的Preferences的Actions panel里面选Expert Mode,以后每次打开ACTION面板都会自动设置为专家模式(专家模式可直接输入代码,初学者学下去就会知道,很多代码无法在普通模式里输入)
AS的一些概念
所有代码都需存于某个地方,可以是frame(帧), button(按钮), or movie clip(电影夹子)。
只要你选择了某按钮或MC,你之后输入的代码就存放在它的上面了,注意此时ACTION面板上方提示为Object Actions。同理你也可以将代码存放于帧,不过此时提示为Frame. Actions。
当你在专家模式的时候仍无法输入代码,你首先要检查你是否选择了frame, button, 或MC来存放代码。
然后我们象学所有语言一样吧,来个HELLO WORLD吧
在ACTION面板输入
var message = “HELLO WORLD”;
trace (message);
然后我们按CTRL和ENTER键,看到结果了吗?
以下两章比较基础。MOOCK是骗演讲费吗?
第三章:解读
第一行代码:var message = “HELLO WORLD”;
告诉FLASH记住一个名字叫message的容器(通常在计算机里称为变量(variable),在FLASH里面,变量可以装文字,和可以装数字)里面装了这样的数据(datum),内容为:“HELLO WORLD”
“=”等号是一个常用的运算符号(operators),在FLASH里面它不是代表相等,而是代表赋值
var 命令的含义是宣布给整个电影,此变量的内容是什么。
第二行代码:trace (message);
就是要FLASH显示message里面的内容,为什么FLASH能输出内容呢,因为当你按CTRL+ENTER又或者在网上打开这个电影的时候,你输入的每一段Action Scrpit代码,都会通过FLASH的解释器(interpreter)来解读然后执行
如果解释器能解释你的代码,他会运行它,并返回你要返回的结果,如果解释器看不懂你的代码,他也会返回错误代码――告诉你错误的原因
通常,我们发给解释器的命令不只命令这么简单,还包括命令的内容例如trace (message); 这个trace输出命令的内容就是message,计算机里就称为参数(argument或parameter),如果一个命令支持多个参数,参数之间一般用“,”来分割
第四章 还有一些概念
表达式(expression):(2 + 3) * (4 / 2.5) - 1可称为一个表达式,“a”+“b”也是表达式,需要解释器运算才得到结果的值,一个相反的概念,不需要运算的直接引用的,称为literal
条件(conditionals):(look at a series of options and make a decision about what to do based on the circumstances)
不翻译了,大概意思就是美女穿着新衣上街,会先看看外面会否下雨,这就叫条件判断啦
if(天气==“下雨”){trace(“还是带把雨伞吧”)}
循环(loop):如果要输出5个数字,你是写5遍trace命令吗?更多的就不行了吧
你可以用while和for命令来完成重复的动作
事件(events):放在frame里面的代码只要电影播放到就会执行,放在MC、button的代码则只在解释器发现预先设置好的事件被触动的时候执行。最典型的就是一下鼠标点击按钮造成press时间啦。
函数(functions):将一组程序打包成一句命令来调用他,其实FLASH里面的很多命令就是函数:trace、play、gotoAndStop等等都是。
第五章 开始第一个版本的选择题的制作
多选题共有两道
如图,大家应该养成一个好习惯,用一个独立的层来放置代码,并把该层放到最上面会更便于修改。
第二层则独立放置Label。不要觉得麻烦,只要你想到世界上大部分好的闪客都是如此做的,你就不会嫌麻烦了。
以下的层放的是选择题的内容,如上图
开始创建题目
在question 1层的第一帧,写上题目“When were movie clips introduced into Flash?” (什么时候FLASH开始引入电影夹子的概念?)
再写上三个选项:Version 1, Version 2, Version 3
跟着我们再做一个用来选择的方框按钮,从Library里面拖出这样的三个按钮,分别放到各个选项的前面。
第二题的创建我们用第一题来做个模版,选择question 1层的第一帧,选择菜单上的Edit>>Copy Frames
再选择question 2的第十帧,Edit>>Paste Frames 将第一题复制过来了
当然问题要改成“When was MP3 audio support added to Flash?” (什么时候FLASH开始支持MP3格式导入?),答案也要改成Version 3, Version 4, Version 5
数据初试化
虽然是个很简单的FLASH,但是象其他复杂的FLASH一样,先告诉FLASH要用到的数据,例如题目的答案等,这是个好习惯,越复杂的FLASH,受惠越多
正常来说定义数据应该LOADING结束之后的。
为了把题目定在第一题,ACTION还需要一句stop;
选择第一帧,在ACTION面板里面输入代码
// init main timeline variables
var q1answer; // user's answer for question 1 第一题用户的答案
var q2answer; // user's answer for question 2 第二题用户的答案
var totalCorrect = 0; // counts number of correct answers 答对的题数
var displayTotal; // text field for displaying user's score 显示用户分数的变量
// stop the movie at the first question
stop();
你会发现//开头的那一行代码都变了色,//代表的是注释,是用来辅助阅读代码用的,对代码执行没有影响(是的,你在里面写笑话,写小说都可以,不会影响你的FLASH的^-^)
我们定义了四个将要用到的变量,用途已经在注释里面写了,写注释也是一个好习惯
关于命名变量名
变量起名displayTotal,意思是 display total,因变量名不能使用空格和破折号,所以用第二个单词的开始字母大写,以此分隔单词
一些程序员也喜欢用下划线:display_total
记住一定要给你的变量起一个一眼就能识别意义的名字
添加label
我们知道第二题是在第10帧的,我们只需要一句AS:gotoAndStop(10); 就可以执行第二个问题了
不过MOOCK告诉你这不是好习惯,因为动画的内容是不断改变的,所以我们应当习惯使用label,即使帧数如何变化,只要label指向正确,不需要修改ACTION都可以继续运行(chocobo再提醒你吧,不要使用相同的label,即使在不同是Scene当中)
好了,我们在label层的第1、10、20分别F6创建关键帧,给他们写上init、q2、quizEnd
要给按钮写上代码了
在三个按钮里面分别写入代码,大同小异的:
按钮一:
on (release) {
q1answer = 1;
gotoAndStop (“q2”);
}
按钮二:
on (release) {
q1answer = 2;
gotoAndStop (“q2”);
}
按钮三
on (release) {
q1answer = 3;
gotoAndStop (“q2”);
}
这三段代码用人类的语言描述,就是:当用户点击某个按钮选择答案后,把他选择的答案记录到q1answer变量中去,然后进入下一题。
on这个单词代表随后的就是一个要触发的事件
release是指在按钮上松开鼠标这样一个事件
当动画执行到这里的时候,三个按钮都会分别监听用户有没有做在按钮上放开鼠标这个动作,一旦发生,按钮就会自动执行大括号{}里面的代码了
若用户选第一个,{}中是:
q1answer = 1; //用q1answer变量记住用户选择的是第一个答案
gotoAndStop (“q2”); //进入下一题
上面我用了注释的方法来解释两句代码,你必须习惯,因为不是所有源程序都有教程,但是好的源程序都会有注释
第二题的按钮与前面相似,只是变量换为q2answer,选择完进入结束的画面,例如第一个,改为:
on (release) {
q2answer = 1;
gotoAndStop (“quizEnd”);
}
结束的画面
结束应该做什么,当然是告诉用户分数啦,写在第20帧,就是label为quizEnd的那帧的代码:
// tally up the user's correct answers
if (q1answer == 3){
totalCorrect = totalCorrect + 1;
}
if (q2answer == 2){
totalCorrect++; //totalCorrect++其实是totalCorrect = totalCorrect + 1;一个更简洁的写法,几乎少打了一半的字母啊。
}
// show the user's score in an on-screen text field
displayTotal = totalCorrect;
用人的语言描述:如果第一题选3,答对数加一,如果第二题选2,答对数加一,把答对题目数赋予另一变量
现在答对的题数是放到变量displayTotal中了,怎么显示?
在quiz end第20帧处建关键帧,键入“Thank you for taking the quiz! Your score final score is: /2”(谢谢回答问题,你最后成绩是答对了 /2道题)
在“/2”之前那个空白的地方放上一个文本框,菜单Text>>Options显示文本面板,把Static Text下拉改为Dynamic Text,顺便把Border/Bg的钩去掉,最后在Variable那一栏填上要显示的变量名displayTotal
你是不是和chocobo一样不耐烦了?快下载www.moock.org/webdesign/lect...oockQuizzes.zip ;吧,里面的quiz.fla就是本章的内容,其他的fla的内容也将会在后面讲到
第六章 再来补充一点AS知识
数据分类是很有必要的,象8005154556这样的一个数字是没有多大意义的,但是如果将他归类到电话号码:800-515-4556,那就有意义了,
(这是WHO的电话啊?是不是MOOCK的?呵呵)
AS里面数据的类型相对其他语言已经算少的,有:
* 字符串String 由一系列的characters组成,可以包含字母,数字和符号,一般用双引号“”扩住(记住不要写了全角的“”)
* 数字Number
* 布尔值Boolean 用于条件判断的时候,只有两个值true和false
* Null and Undefined 这也是数据的类型之一,Null代表变量还没有内容,Undefined是连变量都未定义
* 数组Array 用来按顺序地存放一组数据
* MovieClip 这也是数据的一种吗?你就当它是FLASH特有的一种数据吧,装的就是一个个MC INSTANCE(解释一下吧,MC从library拖到场景中就是一个独立的instance,一个MC可以创立多个instance),还有MC里面的其他数据
* Object 可以是FLASH已经内部定义的,或者是用户写程序时自定义的一类数据
再分类一下
number, string, boolean, undefined, and null,这些属于简单的数据类型,特征是只有一个值
array, object, movieclip. 就可以包含不止一个值
chocobo:其实array也应该算是object,上面这些概念的东西总是有些沉闷,没关系,留下印象,以后用到了,自然会回过来真正了解一遍的
第七章 可以重复的函数(function)
不是用几个例子来示范吗?怎么还不讲例子啊?是的,下一个例子要用到函数,所以再补充点函数知识。(上当了吧?chocobo也上当了,开始翻译的时候没想到这篇东西这么长的,这才讲完第一个例子呢 55~)
一个函数是下面这个样子的:
function funcName () {
statements
}
在ACTION面板里面,function这个单词是变色的,FLASH认识这个单词,它代表后面的就是描述函数的内容
funcName是函数的名字,当你以后要用这函数的时候,就要敲这个名字了(是的,建函数就是为了以后反复调用它)
()小括号里面是参数,什么是参数一会再讲
{}大括号里面的就是函数所要完成功能的一句句代码。
当我们建立函数之后,函数并不运行,只在你用函数的名字调用它出来,才正式开始运行
例如我们有这样一个函数
function sayHi () {
trace(“Hi!”);
}
当我们在FLASH某帧需要sayHi的时候,输入AS:
sayHi();
是不是和最常见的stop();还有play();一样啊?因为它们都是函数嘛
sayHi函数真是智,来个有意义的函数吧。先在场景里放好一个名字叫ball的instance(千万记得要给instance输入名字,否则函数运行没结果别找我)
在第一帧输入这样一个函数:
function moveBall () {
ball._x += 10; // 怕有人不懂,解释一下,_x代表ball的横坐标,ball._x +=10 的意思是ball._x = ball._x + 10 ,这样省略的写法还有 -= *= /= 等等
ball._y += 10;
}
再做一个按钮,按钮的AS:
on (release) {
moveBall();
}
好的,运行,从AS你可以看到,每点一下按钮,执行一次函数,而函数让小球下斜下移动。(FLASH的坐标轴,原点在左上角)
为什么要建立函数呢,就是想更有效率,现在有这个函数已经不用每移动一下写一次AS了,但还是不够,我们需要更有扩展性(flexibility)的函数
这个函数只能移动叫ball的MC,只能向固定的方向移动固定的距离,我们需要可以移动任何MC,向任何方向移动任何距离的函数,这样可以省却很多输入AS的工夫(这就叫一劳永逸,呵呵)
我们的新函数有三个地方是每次调用都不一样的
1、移动的那个MC的名字
2、水平移动的距离
3、垂直移动的距离(呵呵,用极坐标,也可以把2、3说成移动的距离,和移动的角度,不过大家都不习惯极坐标)
为了告诉函数这些变化的地方,我们需要参数(parameters),参数在定义函数的时候就要输入,我们的函数改写好了:
function moveClip (theClip, xDist, yDist) {
theClip._x += xDist;
theClip._y += yDist;
}
当我们要实现原来函数功能的时候,现在调用新函数就变成
moveClip (ball, 10, 10);
定义函数的时候function moveClip (theClip, xDist, yDist) {
这里的theClip等参数(parameters)只是定义,本质上说是不存在的,因为没有内容嘛
当我们用moveClip (ball, 10, 10);调用的时候,ball就输入到theClip中去了,这里的ball称为arguments(偶读得书少,不会翻译)
arguments可以是一个变量,也可以是一个表达式(例如“a”+“b”,先得出结果再传输给函数)只要用逗号隔开各个参数就行
函数如何结束呢
正常来说,函数运行完 {}里所有语句结束,我们也可以用一句AS:return; 让它中途结束,例如:
function say(msg) {
return;
trace(msg);
}
这个函数被调用的时候将什么都不做就结束
return还有更重要的用途:
function sqr(x) { // Squares a number平方
return x * x;
}
a=sqr(2); //a将会被赋予2的平方 4
return更重要的用途就是返回数据
在AS里面,有个内建的函数Math.sqrt(就是说你敲入的时候会变色),其功能和我们刚才做的sqr函数是一样的,现在你该知道内建函数也没什么神秘的,我们一样可以做出相同功能的来。
第八章 第二个版本选择题的制作
读到这你发现什么,我是发现了,MOOCK不是在教AS,他简直是在上编程课。
在第一个版本的制作里你发现了什么缺点?是的,输入了很多次AS,很麻烦。
我们要做的是用函数来集中我们的代码,只有集中了才好修改,越复杂的程序越是如此(想象一下在很多个MC之间查代码,真是头痛,当然是集中一块好)
这个多选题,我们就归结成两个函数吧answer和gradeUser
代码(可以直接看源程序,在上面地址那个ZIP里面的quiz-version2.fla):
大部分的代码都被集中到第一帧了,千万不要被一大堆代码吓着了,代码这么长,只是为了让阅读者看得更清楚而已。(其实越短的代码才越可怕呢,呵呵)
// Stop the movie at the first question
stop ();
// Initialize main timeline variables 定义变量
var displayTotal; // Textfield for displaying user's score
var numQuestions = 2; // Number of quiz questions
var q1answer; // User's answer for question1
var q2answer; // User's answer for question2
var totalCorrect = 0; // Number of questions answered correctly 以上和例一一样
var correctAnswer1 = 3; // The correct choice for question 1 第一题的正确答案
var correctAnswer2 = 2; // The correct choice for question 2 第二题的正确答案
// Function to register user's answers 这个函数的功能是提交答题者的答案
function answer (choice) {
answer.currentAnswer++;
//现在answer.currentAnswer是1,正在提交的是第一题,下一次answer.currentAnswer就变成2,代表提交的是第二题
set (“q” + answer.currentAnswer + “answer”, choice);
// 不复杂不复杂,“q” + answer.currentAnswer + “answer”第一题的时候就是q1answer,第二题是q2answer,把参数choice传过来的值放到两个变量里面而已
if (answer.currentAnswer == numQuestions) {
// 判断是不是两题都答完了,是就转到问题结束帧
gotoAndStop (“quizEnd”);
} else {
gotoAndStop (“q” + (answer.currentAnswer + 1));
}
}
// Function to tally user's score 这个函数是改题的
function gradeUser() {
// Count how many questions user answered correctly 将两个答案和正确答案比较,对就totalCorrect加一
//此处用了一个for循环,大家如有疑问的,可以查AS字典,在帝国就有中文版
for (i = 1; i <= numQuestions; i++) {
// 下面用的eval有必要说一下,它的作用是将字符串和变量组成一个新的变量名,是个很方便的功能
if (eval(“q” + i + “answer”) == eval(“correctAnswer” + i)) {
totalCorrect++;
}
}
// Show user's score in an on-screen text field 将答案显示出来,与第一个例子同
displayTotal = totalCorrect;
}
好了,第一帧的函数写好了,之后每个答案的选择按钮就简单了
例如第一题的选项一,就写:
on (release) {
answer(1);
}
第二题的写法同上(如果你的选择题有很多道,做法都是一样的,只要复制第一题,然后把题目改了就行)
最后在quizEnd帧里面调用改题的函数gradeUser();
分析第二个例子是代码,你会发现比第一个例子精简了很多。
而集中在同一帧的代码,将:
* 更容易修改
* 更容易升级
* 更少的出错机会
* 更容易查错
* 更精简(更少的字节数)
第九章 数组(arrays)
在下一个新版本的多选题里,我们将使用什么AS的特性,来让它更好呢?
那就是数组。
数组就是一系列的数据(MOOCK又开始上课了,chocobo的英文和计算机都不算好,为免误人子弟,概念性的东西尽量精简)
例如这样两个变量储存的数据:
fruit1 = “oranges”;
fruit2 = “apples”;
它们是互相独立的,使用起来很不方便,我们需要的是数组,以下是数组的定义方法,用“&”框住,用“,”分隔开每个元素:
fruitList = [“oranges”, “apples”];
现在两个数据是放到同一个数组里面了,我们开始详细解说数组
数组里面每一个数据称为元素(element)。
而每一个元素都有个独立数字代表所处的位置,数字叫索引(index),注意! 第一个数据的索引是0,第二个才是1
要按索引来提出数据,我们要用一个运算符&,例如使用fruitList第一个元素赋值给a:
a=fruitList
篇7:Flash动态遮罩高级教程
动态|高级|教程
在上一篇教程www.webjx.com/htmldata/2005-03-09/1110349315.html中我有意的避开curveTo因为它相对于lineTo来说多少有些复杂,然后这种效果我认为变化多会优于一味的使用lineTo.
首先我们需要先了解一下curveTo的相关命令:
CURVETO命令:
在下面的例子中我们要用到的命令如下:
代码:
MovieClip.beginFill()
MovieClip.endFill()
MovieClip.lineTo()
MovieClip.curveTo()
前面三行我们已在第一篇教程学习过,现在只剩下curveTo,curveTo(controlX,controlY,endX,endY)将从startX,startY开始绘制一条二次方曲线至endX,endY, startX,startY的位置决定于使用moveTo,lineTo,或curveTo得到的最后一点,controlX,controlY 控制着两点之间的曲度,你可以把controlX,controlY认为是一个磁性点,它会吸附曲线靠近它,它的工作过程有些象BEZIER贝赛尔曲线,不同的是每一条曲线只有只能有一个控制点。
现在需要看一下我们的动态遮罩的工作过程,它要经过三个边续的过程,如下图所示:
如上图你所看到,遮罩的组成是由最初上面的一条直线然后变形成为4边的形状也就是面的蓝色线条将屏幕划分为4边,然后再变形为红色的线条,最后形成整个矩形。十字代表的是控制点的大致位置。
在这里面你需要注要注意的是第一条和最后一条并不是曲线,而是直线,所以你可将你的按制点放在任何地方,这也给我们增加了许多弹性空间。在后面你将会看到。
变形形体
我们必须要掌握将一个形体变为另一个形体,比如蓝色形状变为红色形状,这个看起来比较麻烦,实际上很简单,就象一个物体从A点移到B点是一个性质。我们将移到第一条曲线的三个点至第二条曲线三个点的位置,下面我们来看一下例子,将曲线c变形为曲线J。
代码:
//Create movie clip and mask
//counter = -1;
//创建遮罩
_root.createEmptyMovieClip('line', 0);
animInt = setInterval(doAnim, 17);
animDir = 1;//用来控制方向的变量
//定义函数
function doAnim()
{
var currMC = _root.line;
var time = animIndex/60;
var dist = time;
with(currMC)
{
//c曲线的位置: (150, 25), (25,100), (150,175)
//j曲给的位置: (150, 25), (125,200), (50,125)
clear();
lineStyle(0x000000);
moveTo(150,25);
curveTo(25+100*dist,100+100*dist,150-100*dist, 175-50*dist);
}
animIndex += animDir;
if(animIndex >= 60)
{
animDir = -1
}
if(animIndex <= 0)
{
animDir = 1
}
}
这段代码中是将c曲(150,25)(25,200),(150,175)变形为J曲线(150, 25), (125,200), (50,125)
注意,这段代码只能在FLASHMX中运行。如果想在FLASHMX2004中运行,你需要在定义一下animIndex在animDir=1;下面加入一行var animIndex=0;测试你的影片,观看结果。
观看演示1
开始时创建一个影片剪加line,在line的内部绘制变形曲线,setInterval每17豪秒循环绘制一次,变量animIndex用来跟踪曲线绘制到的位置,这个例子中我们分成了60步来绘制,time变量的范围是从0到1,决定于animIndex,同时将其附给dist,用来创建现线动画。
即然dist的变量范围是从0到1,那么很明显我们用到了一个公式从A点到B点
代码:
x = startX + dist*deltaX;
y = startY + dist*deltaY;
如下我们的应用:
curveTo(25+100*dist,100+100*dist,150-100*dist, 175-50*dist);
在这个公式中startX和startY是开始点的坐标,deltaX和deltaY分别是x和y到开始点和结束点的距离。
Easing, bouncing and other transitions
缓动,弹性和其它运动方式
可能在一开始你就会想我们为什么会不厌其烦的使用变量time和dist,那么现在让我们来看一下他们之间的关系,你就会知道我们为什么要用它,
如上果你所看到的竖轴代表Dist,水平轴代表time.他们之间的关系目前是线性,也是就dist=time.图上的斜线代表动画的速度。在这个例子中动画的速度是恒定的。现在假如我们想做成开始时速度很快到结速时无速度,则我们只需要在在t=0时加大红线的斜率,而在t=1时使红线无斜率就可以了。这实际上就是倒转过的抛物线或是三角正弦,如果想用其它的运动方式我们可以创建不同的dist和time的关系,来得到更有趣的效果,下面是一些创建好的关系,可能对你会有用处:
你可能会对Robert Penner's transition classes感兴趣。原理都是一样的。
将代码合在一起
代码:
//全局变量决定于你的影片宽度
mWidth = 400;
//创建影片剪辑和遮罩
counter = -1;
createMovieClip();
animInt = setInterval(doAnim, 17);
function createMovieClip()
{
counter++;
attachMovie('pic' add (counter % 2), 'pic' add counter, counter);
createEmptyMovieClip('mask' add counter, counter + 10000);
this['pic' add counter].setMask(this['mask' add counter]);
}
function doAnim()
{
var currMC = _root['mask' add counter];
if(animIndex < 15)
{
var time = animIndex/15;
var dist = 0.5*Math.sin(Math.Pi*(time-0.5)) + 0.5;
with(currMC)
{
clear();
beginFill(0x000000);
lineTo(mWidth,0);
lineTo(mWidth,dist*125);
curveTo(250,dist*40,0,10*dist);
endFill();
}
}
else if (animIndex < 35)
{
var time = (animIndex-15)/20;
var dist = 0.5*Math.sin(Math.Pi*(time-0.5)) + 0.5;
with(currMC)
{
clear();
beginFill(0x000000);
lineTo(mWidth,0);
lineTo(mWidth,125);
curveTo(250-100*dist,40+150*dist,0,10+190*dist);
endFill();
}
}
else if (animIndex <= 50)
{
var time = (animIndex-35)/15;
var dist = 0.5*Math.sin(Math.Pi*(time-0.5)) + 0.5;
with(currMC)
{
clear();
beginFill(0x000000);
lineTo(mWidth,0);
lineTo(mWidth,125+75*dist);
curveTo(150,190+10*dist,0,200);
endFill();
}
}
animIndex++;
if(animIndex >50)
{
animIndex = 0;
_root['pic' add (counter - 1)].removeMovieClip();
_root['mask' add (counter - 1)].removeMovieClip();
createMovieClip();
}
}
这段代码使用了两个函数,createmovieclip用来将图片贴加到场景中并设置MASK,cunter用来跟踪图片的实例名称。
Doanim函数被每20豪秒调用一次,整个遮罩形成过程与范例上一个例子一样分成三部执行。对于缓动方式你可选择其它的方式,只需要将DIST的值改为其它的公式就可以。
观看演示2
总结:在这两篇教程中我们先后学习了基本的动态遮罩,和动态绘制曲线来形成遮罩,两者基本的原理相同,尤其你应注意的是如何加入easing,bouncing等等。我想这对你可能是有用的。
源文件下载:dymask2.zip
★ 学习计算机技巧
★ 单片机的实习报告
★ Silverlight游戏设计:(五)面向对象的思想塑造游戏对象
★ 单片机实习报告
【Flash教程:数组知识概述(共7篇)】相关文章:
FLASH制作个性的旋转圆形网页导航2022-05-06
C语言程序设计课件和教学网站设计论文2023-07-18
帝国cms列表简介信息问题2022-05-24
FLASH文字颜色缓动特效2023-01-26
地下工程有限元图形系统的面向对象开发2023-08-07
《递归算法的实现》教学设计2023-09-25
120个solidworks实例教程2022-11-05
嵌入式系统的实习报告2023-08-04
确保PHP应用程序的安全[2]WEB安全2022-04-30
嵌入式实习总结2023-02-11