■算法大全

■[AS 功能代码教程15] 点间距离公式 [FL基础理论大师]
■[Flash基础理论课16] 矩阵革命 [双重循环]
■[AS 功能代码教程14] 鱼眼放大镜 [FL基础理论大师]
■[AS 功能代码教程13] 贪吃蛇游戏制作 [FL基础理论大师]
■[Flash基础理论课15] 绚酷鼠标 [目标移动]
■[Flash基础理论课14] 制作Loading [Loading]
■[杂谈四] JavaScript就这么回事 [二次编辑贴]
■[AS 功能代码教程12] 填色游戏 [FL基础理论大师]
■[Flash基础理论课13] FL记事本 [SharedObject]
■[杂谈四] AS代码优化技巧 [综合贴]
■[AS 功能代码教程11] 图片转场效果 [FL基础理论大师]
■[Flash基础理论课12] 倒计时系统 [getTime]
■[杂谈四] 程序员应该学C语言的十个理由
■[AS 功能代码教程10] 数据结构排序算法 [FL基础理论大师]
■[Flash基础理论课11] AS文本计算器 [文本类]
■[AS 功能代码教程09] 点阵字效果 [FL基础理论大师]
■[AS 功能代码教程08] BitmapData动态效果 [FL基础理论大师]
■[Flash基础理论课10] 缓动效果 [Tween类]
■[杂谈三] 微软Silverlight和Flash短兵相接
■[AS 功能代码教程07] 百变图 [FL基础理论大师]
■[AS 功能代码教程06] AS绘图总结及补充 [FL基础理论大师]
■[Flash基础理论课09]满天星及变幻线[MC.onEnterFrame]
■[Flash基础理论课08]旋转花朵[for...in]
■[游戏赏玩]吸泡泡
■[Flash基础理论课07]制作控制滑块[startDrag]
■[杂谈二]人类的15个欲望与游戏设计
■[AS 功能代码教程04] 进阶三角函数及应用 [FL基础理论大师]
■[Flash基础理论课06]制作移动角色[Key类]
■[Flash基础理论课05]制作摇奖盘[onEnterFrame]
■[AS 功能代码教程05] 打字机效果及字符串概念 [FL基础理论大师]
■[AS 功能代码教程03] 基础三角函数及应用 [FL基础理论大师]
■[AS 功能代码教程02]数字魔方及数组概念[FL基础理论大师]
■[AS 功能代码教程01]通用延迟代码及FPS概念[FL基理大师原创]
■[Flash基础理论课04] 制作音乐播放器[Sound类]
■[Flash基础理论课03]制作简易涂鸦板[画线指令]
■[Flash基础理论课02]制作个性鼠标[updateAfterEvent]
■[Flash基础理论课01]制作时钟[Date类]
■[杂谈一] 什么是真正的Flash高手?

希望朋友们多提保贵议建,您的题问和课题将成文我前进的最大动力。

 

很不错的,我把内容复制如下。感谢分享:
1。[杂谈五] 成为编程高手的八大奥秘
不知不觉做软件已经做了十年,有成功的喜悦,也有失败的痛苦,但总不敢称自己是高手,因为和我心目中真正的高手们

比起来,还差得太远。世界上并没有成为高手的捷径,但一些基本原则是可以遵循的。

1.扎实的基础

  数据结构、离散数学、编译原理,这些是所有计算机科学的基础,如果不掌握它们,很难写出高水平的程序。程序人

人都会写,但当你发现写到一定程度很难再提高的时候,就应该想想是不是要回过头来学学这些最基本的理论。不要一开

始就去学OOP,即使你再精通OOP,遇到一些基本算法的时候可能也会束手无策。因此多读一些计算机基础理论方面的书籍

是非常有必要的。

2.丰富的想像力

  不要拘泥于固定的思维方式,遇到问题的时候要多想几种解决问题的方案,试试别人从没想过的方法。丰富的想像力

是建立在丰富的知识的基础上,除计算机以外,多涉猎其他的学科,比如天文、物理、数学等等。开阔的思维对程序员来

说很重要。

3.最简单的是最好的

  这也许是所有科学都遵循的一条准则,复杂的质能转换原理在爱因斯坦眼里不过是一个简单得不能再简单的公式:

E=mc2。简单的方法更容易被人理解,更容易实现,也更容易维护。遇到问题时要优先考虑最简单的方案,只有简单方案

不能满足要求时再考虑复杂的方案。

4.不钻牛角尖

  当你遇到障碍的时候,不妨暂时远离电脑,看看窗外的风景,听听轻音乐,和朋友聊聊天。当我遇到难题的时候会去

玩游戏,当负责游戏的那部分大脑细胞极度亢奋的时候,负责编程的那部分大脑细胞就得到了充分的休息。当重新开始工

作的时候,我会发现那些难题现在竟然可以迎刃而解。

5.对答案的渴求
  人类自然科学的发展史就是一个渴求得到答案的过程,即使只能知道答案的一小部分也值得我们去付出。只要你坚定

信念,一定要找到问题的答案,你才会付出精力去探索,即使最后没有得到答案,在过程中你也会学到很多东西。

6.多与别人交流

  三人行必有我师,也许在一次和别人不经意的谈话中,就可以迸出灵感的火花。多上上网,看看别人对同一问题的看

法,会给你很大的启发。

7.良好的编程风格

  注意养成良好的习惯,代码的缩进编排,变量的命名规则要始终保持一致。大家都知道如何排除代码中错误,却往往

忽视了对注释的排错。注释是程序的一个重要组成部分,它可以使你的代码更容易理解,而如果代码已经清楚地表达了你

的思想,就不必再加注释了,如果注释和代码不一致,那就更加糟糕。

8.韧性和毅力

  这也许是“高手”和一般程序员最大的区别。高手们并不是天才,他们是在无数个日日夜夜中磨炼出来的。成功能给

我们带来无比的喜悦,但过程却是无比的枯燥乏味。你不妨做个测试,找个10000以内的素数表,把它们全都抄下来,然

后再检查三遍,如果能够不间断地完成这一工作,你就可以满足这一条。


2。[AS 功能代码教程15] 点间距离公式 [FL基础理论大师]
两点间距离
Math.sqrt(Math.pow((p1._x-p2._x),2)+Math.pow((p1._y-p2._y),2))
由这个公式可以推导出某点与原点距离公式:
因为原点坐标为(0,0),所以公式变形如下
Math.sqrt(p1._x * p1._x + p1._y * p1._y)
下面我们就来运用这两个公式来制作一些效果
实例一: 旋转指针
思路:
求一个夹角的θ方法很多如:
distance.jpg
正弦函数 sinθ=y/r
余弦函数 cosθ=x/r
正切函数 tanθ=y/x
余切函数 cotθ=x/y
正割函数 secθ=r/x
余割函数 cscθ=r/y
这些三角函数都可以求出同一个夹角θ
在本实例中只使用 atan 和 acos 而没有使用其它三角函数是因为他们的返回值都是一个任意数字,而其它函数的返回值

均为限定的数字。
步骤一:
    绘制一指针,保存为影片剪辑,注册点在指针根部,实例名为"pointer"

步骤二:
在第一帧加入AS代码(正切函数):
pointer.onMouseMove = function() {
var dx = _xmouse-this._x;
var dy = _ymouse-this._y;
var theta = Math.atan2(dy, dx);
//使用正切函数求出夹角
this._rotation = theta/Math.PI*180;
//将弧度转换为角度
};

在第一帧加入AS代码(反余弦函数):
pointer.onMouseMove = function() {
var dx = _xmouse-this._x;
var dy = _ymouse-this._y;
var r = Math.sqrt(dx*dx+dy*dy);
//r为点与鼠标的直线距离,这里也是斜边r
var theta = Math.acos(dx/r)*Math.abs(dy)/dy;
//使用反余弦函数求出夹角
this._rotation = theta/Math.PI*180;
//将弧度转换为角度
};
实例二: 泡泡效果
思路:
通过判断鼠标的移动距离改变复制出泡泡的大小,移动得越远,泡泡越大

步骤一:
    绘制泡泡,保存为影片剪辑,连接—>导出—>标志符"bubble"
步骤二:
在第一帧加入AS代码:
var n:Number = 0;
var old_x, old_y;
//这两个全局变量用于存储前一次的鼠标位置
_root.onMouseMove = function() {
var dx = _xmouse-old_x;
var dy = _ymouse-old_y;
var distance = Math.sqrt(dx*dx+dy*dy);
//求出本次鼠标位置和前一次鼠标位置的距离
var p = attachMovie("bubble", "b"+n, n);
p._x = _xmouse;
p._y = _ymouse;
p._width = p._height=distance;
//用得出的距离为泡泡设置尺寸
p.onEnterFrame = function() {
  if (this._alpha>0) {
   this._xscale = this._yscale += 5;
   this._alpha -= 5;
   //做一个泡泡变大消失的效果
  } else {
   delete this.onEnterFrame;
   removeMovieClip(this);
   //泡泡看不见后,别忘了删除他的影片和函数,否则会卡哟
  }
};
old_x = _xmouse;
old_y = _ymouse;
//保存本次鼠标位置作为前一次鼠标的位置
n++;
};

实例三: 辐射点效果
思路:
1.把点以行列的形式平均分配到舞台上
2.用点间距离公式,判断每个点与鼠标的距离
3.缩放值 = 距离 - 120

4.当120<距离<220时,则缩放值开始变小[100~0],表现为向内开始变小
5.当距离<120时,则缩放值小于0,表现为向内开始变大,开始走向负数

6.当距离为0时,则缩放值为 -120,表现为鼠标中心位置上较大的那些圆
步骤一:
    绘制一黑点,尺寸为20*20,保存为影片剪辑,
    注册点在中心,连接—>导出—>标志符"dot"
步骤二:
var size = 20;
//黑点的大小
var Colum = Math.floor(Stage.width/size);
var Row = Math.floor(Stage.height/size);
for (var i = 0; i<Colum; i++){
for (var j = 0; j<Row; j++){
  var p = _root.attachMovie("dot", "d"+(i*Row+j), i*Row+j);
  p._x = (size/2)+i*size;
  p._y = (size/2)+j*size;
  //以行列的形式把点平均分配到舞台上
  p.onMouseMove = function() {
   var dx = this._x-_xmouse;
   var dy = this._y-_ymouse;
   var distance = Math.sqrt(dx*dx+dy*dy);
   var d = distance-120;
   //如果距离大于220,则不进行缩放,距离小于220则为进行缩放
   if (d>100) {
    d = 100;
   }
   //或 d = d>100 ? 100 : d;
   this._xscale = this._yscale=d;
  };
}
}
实例四: 狡猾的小球
先复习一下圆的参数方程:x坐标 = R*cosθ+m; y坐标 = R*sinθ+n
根据正弦函数 sinθ=y/r 和 余弦函数 cosθ=x/r推出圆的参数方程为:
x坐标 = R*(x/r)+m; y坐标 = R*(y/r)+n 其中(m,n)为原点坐标。
思路:
1.使用变型的圆参数方程: x= R*(x/r)+m; y= R*(y/r)+n
2.为了让小球躲得更远可以加入新圆心坐标dif_x, dif_y
3.得出球的新位置 =球的初始位置—(圆心位置+圆上的位置)
步骤一:
    绘制一黑点,尺寸为20*20,保存为影片剪辑,
    注册点在中心,连接—>导出—>标志符"dot"
步骤二:
在第一帧加入AS代码:
var size = 30;
//比点的尺寸大出10像素作为行列间距
var Colum = Math.floor(Stage.width/size)-2;
var Row = Math.floor(Stage.height/size)-2;
//行数列数减2,目的是在周围空出2行
var Max = 1000;
//反映及影响圆半径的常量
for (var i = 0; i<Colum; i++){
for (var j = 0; j<Row; j++){
  var p = _root.attachMovie("dot", "d"+(i*Row+j), i*Row+j);
  p._x = p.oldx=20+(size/2)+i*size;
  p._y = p.oldy=20+(size/2)+j*size;
  //以行列的形式把点平均分配到舞台上,同时保存初始位置为oldx,oldy
  p.onEnterFrame = function() {
   var dx = _xmouse-this._x;
   var dy = _ymouse-this._y;
   var r = Math.sqrt(dx*dx+dy*dy);
   //r为点与鼠标的直线距离,这里也是斜边r
   var Circle_x = (dx/r)*Max/r;
   var Circle_y = (dy/r)*Max/r;
   //计算出该点在圆上的位置,Max/r为半径,所以r越小半径越大
   var dif_x = (this.oldx-this._x)/2;
   var dif_y = (this.oldy-this._y)/2;
   //以球的新位置与初始位置之差为新的圆心
   this._x = this.oldx-(dif_x+Circle_x);
   this._y = this.oldy-(dif_y+Circle_y);
   //得出球的新位置=球的初始位置—(圆心位置+圆上的位置)
   //之所以减去(圆心位置+圆上的位置): 让小球位置与鼠标位置相反
  };
}
}

教程到此结束
QQ:147461195(FL基理大师)

 

3。[Flash基础理论课16] 矩阵革命 [双重循环]
在本次课中我们将介绍两种方法来完成该效果,重点掌握双重循环语句
还要介绍 TextField._alpha 方法不可用的解决办法
单循环:
for (i=0; i<5; i++) {
trace("i="+i);
}

运行结果如下:
i=0
i=1
i=2
i=3
i=4

双重循环:
就是在for循环中再加入一个for循环
for (i) {
   for(j) {}
}

下面看一个双重循环的例子
for (i=0; i<5; i++) {
for (j=0; j<3; j++) {
  trace("i="+i+" j="+j);
}
}
运行结果如下:
i=0 j=0
i=0 j=1
i=0 j=2
i=1 j=0
i=1 j=1
i=1 j=2
i=2 j=0
i=2 j=1
i=2 j=2
i=3 j=0
i=3 j=1
i=3 j=2
i=4 j=0
i=4 j=1
i=4 j=2
i=5 j=0
i=5 j=1
i=5 j=2
i=6 j=0
i=6 j=1
i=6 j=2
i=7 j=0
i=7 j=1
i=7 j=2
i=8 j=0
i=8 j=1
i=8 j=2
i=9 j=0
i=9 j=1
i=9 j=2

 

总结一下可以这样写:
当i=0时,j=0, j=1, j=2
当i=1时,j=0, j=1, j=2
当i=2时,j=0, j=1, j=2
当i=3时,j=0, j=1, j=2
当i=4时,j=0, j=1, j=2

我们再形象地解释一下双重循环的意思:
把 for (i=0;i<5;i++){...} i从0到4,循环了5次,就把这五次循环表示为5个人
"小赵","小钱","小孙","小李","小周"
把 for (j=0;j<3;j++){...} j从0到2,循环了3次,就把这三次循环表示为3件事
"买菜","买肉","买米"
就相当于:
当i="小赵"时,他要去 j="买菜", j="买肉", j="买米"
当i="小钱"时,他要去 j="买菜", j="买肉", j="买米"
当i="小孙"时,他要去 j="买菜", j="买肉", j="买米"
当i="小李"时,他要去 j="买菜", j="买肉", j="买米"
当i="小周"时,他要去 j="买菜", j="买肉", j="买米"

本节中将用到的利用双重循环实现行列分配的问题
columrow2.jpg

已知库中有一个链接名为 mc 的影片剪辑,为一个圆,大小为30,注册点在左上
var size = 30;
var Colum = Math.floor(Stage.width/size);
//根据圆大小,确定横向能容纳多少个圆,就是有多少个列
var Row = Math.floor(Stage.height/size);
//根据圆大小,确定纵向能容纳多少个圆,就是有多少个行
for (var i = 0; i<Colum; i++){
for (var j = 0; j<Row; j++){
  var p = _root.attachMovie("dot", "d"+(i*Row+j), i*Row+j);
//i*Row+j 确保每个影片的新名字和深度都不相同

//这里也可使用getNextHighestDepth()
  p._x = i*size;
  p._y = j*size;
//设置圆的位置,双循环的意思是: 有 Colum 行,且每一行中都有 Row 个列
}
}

解释过来就是:
当 x 坐标 = 第1列时,分配Row个圆,y坐标从0到Row-1
当 x 坐标 = 第2列时,分配Row个圆,y坐标从0到Row-1
当 x 坐标 = 第3列时,分配Row个圆,y坐标从0到Row-1

                        ... ...
当 x 坐标 = 第Colum-1列时,分配Row个圆,y坐标从0到Row-1

 

矩阵革命:

制作方法(一)

思路:
1.制作一个有若干帧的影片剪辑,每一帧都代表一个随机的字母或数字;
2.设置影片文本的大小为30,用舞台大小除以字母大小,确定每行每列能容纳多少文本;
3.每列容纳字符个数为Colum个,共Row列;
4.根据Colum和Row的确定影片的行位置和列位置。

步骤1:

columrow2.jpg

    制作一个影片剪辑,有若干帧,每帧中一个静态文本框

    内容为一个字母或一个数字
    字体: Arial,字号: 30,加粗,颜色:0x00FF00
    连接—>导出—>字符"txt"

步骤2:
在第一帧中写入代码
var size = 32;
//比文本框大出2个象素,做为行列间距
var Colum = Math.floor(Stage.width/size);
//按照字符大小,确定每列能容纳多少个字符
var Row = Math.floor(Stage.height/size);
//按照字符大小,确定每行能容纳多少个字符
for (var i = 0; i<Colum; i++){

for (var j = 0; j<Row; j++){
  var p = _root.attachMovie("txt", "t"+(i*Row+j), i*Row+j);
  p._x = i*size;
  p._y = j*size;
  //安排每个新字符影片的位置,每一行中都有Row个列
  p.onEnterFrame = function() {
   this.gotoAndStop(random(this._totalframes));
   //每次随机取一帧,实现随机字母或数字
   this._alpha = random(100);
   //随机的设置影片剪辑的透明度
  };
}
}


在写本节内容时,原本只想用方第二种方法(纯AS编写),但在测试中发现 TextField._alpha 和TextField._rotation

方法是“无效”的,随后在网络上发现了解决的办法,下面我们先来看一下纯AS编写的部分,然后在看“失效”的解决办

法。

 

制作方法(二)
思路:这次只使用创建TextFiled的方法,而不是再使用影片剪辑中的方法

在第一帧中加入以下代码
var t_f:TextFormat = new TextFormat();
t_f.size = 20;
t_f.font = "Arial";
//设置字体格式
var Colum = Math.floor(Stage.width/t_f.size);
var Row = Math.floor(Stage.height/t_f.size);
for (var i = 0; i<Colum; i++) {

  for (var j = 0; j<Row; j++) {
var T=_root.createTextField("txt"+(i*Row+j),i*Row+j,0,0,0,0)
  //创建文本框
  T._x = i*t_f.size;
  T._y = j*t_f.size;
  //设置其坐标位置
  T.textColor = 0x00ff00;
  T.setNewTextFormat(t_f);
  T.autoSize = true;
  T.selectable = false;
  //T.embedFonts = true;
  //设置文本框属性
}
}
_root.onEnterFrame = function () {
for (var i = 0; i<Colum*Row; i++) {
  if (Math.random()<0.5) {
   this["txt"+i].text = String.fromCharCode(65+random(26));
   //随机的字母
  } else {
   this["txt"+i].text = String.fromCharCode(48+random(10));
   //随机的数字
  }
  //this["txt"+i]._alpha = random(100);
  //随机的文本透明度
}
};


解释一下被注释掉的两句:
T.embedFonts = true;
使用嵌入字体轮廓进行呈现,前提是在库中要导入该字体元件
this["txt"+i]._alpha = random(100);
在T.embedFonts = true; 设置文本框透明度

 

TextField._alpha 和 TextField._rotation 方法“失效”解决办法

1.在库中创建字型
<1>点库右上角的倒三角,选择“新建字型...”
<2>建立字体元件(和你的字体名字变量一样),然后选择字体
<3>右键选择你刚创立的元件。选择“为ActionScript导出”写入链接名,本节中为"Arial"

2.设置 TextField._embedFonts = true

使用嵌入字体轮廓进行呈现,是使用 TextField._alpha 和TextField._rotation 的前提,嵌入字体轮廓就是指在库中导

入字型。

好了现在可以加上注释掉的两句使一使效果了
教程到此结束。QQ:147461195(FL基理大师)

 

4。[AS 功能代码教程14] 鱼眼放大镜 [FL基础理论大师]
本节加了星号,借黑羽的话:“本节的内容稍微有些难度,如果不明白,可以暂时不看,待日后碰到类似问题时,再来查

阅”

下面我们先用图解法来解释一下本实例

思路:
1.鱼眼放大镜是于若干个渐小的圆组成的;
2.使每个圆都去遮罩一个渐大的图片来实现,里面的小圆遮罩大较图片,外面的大圆遮罩较小图片;
3.还有最后一个重要的步骤是"对焦",由于图片是渐大的,所以鼠标所在的一个点位对于小图来说也许是头部,而对于大

图来说也许都到了场外,那么显示出的效果就错了。使用"对焦"可以让鼠标指在小图上是头部,大图上也要是头部,这么

说给大家一个印象,下面请看图解.

图解:

Mag4.jpg

1.首先在舞台上放入两个影片剪辑,其中一个是图片,实例名"pic",注册点在左上(0,0);另一个是圆,大小:200*200

,实例名"ball",注册点在中心;

 

Mag4.jpg

2.鱼眼放大镜是于若干个渐小的圆组成,让这些圆作为镜片,重叠在一起,同时成像,圆(镜片)的数量越多,成像效果越

细,图中数量为3
代码如下:
var Count:Number = 3;
//复制圆(镜片)的数量
for (var i = 0; i<Count; i++){
var b = ball.duplicateMovieClip("B"+i, i*2+1);
//复制圆
b._xscale = b._yscale=(1-i/Count)*100;
//圆的缩放= (1-第i个圆/圆的数量)*100,例:100~90~80~70
}


Mag4.jpg

3.每个圆都加载一个渐大的图片,先来创建这些渐大的图片,图的数量为3
  代码如下:
var Count:Number = 3;
//复制圆(镜片)的数量
var Zoom:Number = 0.08;
//图片放大的递增倍数
for (var i = 0; i<Count; i++){
var dif = 1+i*Zoom;
//缩放比(dif)为递增量,例:1.00~1.08~1.16~1.24...
var p = pic.duplicateMovieClip("P"+i, i*2);
//复制图片
p._xscale = p._yscale=dif*100;
//图片缩放=递增量*100,例:100~108~116~124...
}


Mag4.jpg

4.综合上述实现,里面的小圆遮罩大较图片,外面的大圆加载较小图片,再加入一句保存初始缩放比的语句
var Count:Number = 30;
//复制圆(镜片)的数量
var Zoom:Number = 0.08;
//图片放大的递增倍数
for (var i = 0; i<Count; i++){
var dif = 1+i*Zoom;
//dif为递增量,例:1.00~1.08~1.16~1.24...
var b = ball.duplicateMovieClip("B"+i, i*2+1);
//复制圆
b._xscale = b._yscale=(1-i/Count)*100;
//圆的缩放= (1-第i个圆/圆的数量)*100,例:100~90~80~70
b.Zoom = dif;
//保存图片的缩放比
var p = pic.duplicateMovieClip("P"+i, i*2);
//复制图片
p._xscale = p._yscale=dif*100;
//图片缩放=递增量*100,例:100~108~116~124...
p.setMask(b);
//进行遮罩
}

5."对焦"
请大家看一看下面的演示动画,也许能让你了解他的含义

Mag4.jpg

这是两张没有"对焦"的图片,大家注意,如果鼠标在小图的红星位置,那么对于大图来说,也许是人物的脸部,而不是大

图的红星位置
Mag4.jpg

这是两张执行"对焦"后的图片,如果鼠标在小图的红星位置,那么对于大图来说,也要在红星位置上
如何实现"对焦"功能,请看下面代码:
_root.onMouseMove = function() {
for (var i = 1; i<=Count; i++) {
  var balls = this["B"+i];
  balls._x = _xmouse;
  balls._y = _ymouse;
  //使每个镜片都跟着鼠标移动
  this["P"+i]._x = _xmouse-(_xmouse-pic._x)*balls.Zoom;
  this["P"+i]._y = _ymouse-(_ymouse-pic._y)*balls.Zoom;
  //调整每个复制出的图片的位置
  //新的位置 = 鼠标位置 — (鼠标位置 — 原图pic的位置) * 缩放比
}
};

根据 "对焦" 公式:
新的位置 = 鼠标位置 — (鼠标位置 — 原图pic的位置) * 缩放比
本实例中,原图pic的位置为左上(0,0)点,所以,公式可以变形为:
新的位置 = 鼠标位置 — 鼠标位置 * 缩放比

这个公式也是本节的难点,就以原图位置在左上(0,0)为例

如果鼠标在右边,那么新位置肯的为负数,新位置向左移,因为缩放比是大于1.00的数;反之,则是两个负数相加,新位

置向右移
好的,整个思路就这些,下面给出完整过程

步骤1:
    首先在舞台上放入两个影片剪辑

    其中一个是图片,实例名”pic”,注册点在左上(0,0);

    另一个是圆,大小:200*200,实例名”ball”,注册点在中心
步骤2:
在第一帧加入AS代码
var Count:Number = 30;
//复制圆(镜片)的数量
var Zoom:Number = 0.08;
//图片放大的递增倍数
for (var i = 0; i<Count; i++){
var dif = 1+i*Zoom;
//dif为递增量,例:1.00~1.08~1.16~1.24...
var b = ball.duplicateMovieClip("B"+i, i*2+1);
//复制圆
b._xscale = b._yscale=(1-i/Count)*100;
//圆的缩放= (1-第i个圆/圆的数量)*100,例:100~90~80~70
b.Zoom = dif;
//保存图片的缩放比
var p = pic.duplicateMovieClip("P"+i, i*2);
//复制图片
p._xscale = p._yscale=dif*100;
//图片缩放=递增量*100,例:100~108~116~124...
p.setMask(b);
//进行遮罩
}
_root.onMouseMove = function() {
for (var i = 1; i<=Count; i++) {
  var balls = this["B"+i];
  balls._x = _xmouse;
  balls._y = _ymouse;
  //使每个镜片都跟着鼠标移动
  this["P"+i]._x = _xmouse-(_xmouse-pic._x)*balls.Zoom;
  this["P"+i]._y = _ymouse-(_ymouse-pic._y)*balls.Zoom;
  //调整每个复制出的图片的位置
  //新的位置 = 鼠标位置 — (鼠标位置 — 原图pic的位置) * 缩放比
}
};


教程到此结束
QQ:147461195(FL基理大师)


5。FL基础理论大师———贪吃蛇游戏   按'方向键'开始
思路:
1.首先规定蛇的运动区域宽度(stagew)和高度(stageh)
2.增加键盘侦听,获得键控代码,如果该键与前一个键是反向的则不予改变
3.初始化中, 请注意:蛇头、蛇身、食物的大小均为 7 象素
4.每一次移动的步长(Move)均为8象素,以实现身体为一格一格的效果
5.吃到食物后,蛇身(body)长度增加5个单位,复制出5个身体
6.履带式前进:从尾部开始,后一个跟随前一个的位置,最前面的跟随蛇头

 

图示:
1.整体思路

SnakeTree.jpg

2.蛇头、蛇身、食物的大小均为 7 象素,步长 8 象素

SnakeTree.jpg


步骤1:

SnakeTree.jpg

  *绘制一个正方形做(代表蛇头、蛇身、食物),尺寸随意,保存为影片剪辑
   注册点在左上(0,0),连接—>导出—>标志符"block"

  *FPS为18左右
步骤2:
加入AS代码

//========== 绘制出蛇活动的区域 ==========
var stagew:Number = 447;
var stageh:Number = 255;
beginFill(0xeeeeee);
moveTo(0, 0);
lineTo(stagew, 0);
lineTo(stagew, stageh);
lineTo(0, stageh);
endFill();
//========== 创建一个文本框用于显示信息 ==========
_root.createTextField("txt", -100, 1, 255, 400, 30);
txt.text = "贪吃蛇游戏   按'方向键'开始";
//========== 建立键盘侦听 ==========
Key.addListener(txt);
//使用一个已有的对象txt作侦听,免去了新建侦听对象了,节约了空间
var NowKey:Number;
//NowKey全局变量用于存储当前按下的键
txt.onKeyDown = function() {
var c = Key.getCode()-37;
//c= 左键0 上键1 右键 2 下键3
if ((c<4) && (Math.abs(NowKey-c) != 2)) {
  NowKey = c;
//如果蛇正在向左移动那么他就不能向右移动,如果正向上移动就不能向下移动
//左(0)和右(2)相差2,上(1)和下(3)相差2,所以如果他们相差2则该键无效

}
};
//========== 下面是一系列初始化 ==========
_root.attachMovie("block", "head", -1, {_width:7, _height:7});
//首先创建蛇头,它的大小为7像素
var Move:Number = 8;
//每次移动的距离比蛇头多出1像素,这样就可以做出一格一格的效果了
head._x = head._y=20*Move;
//蛇头的起点位置要(移动距离的倍数)
var body:Number = 0;
//蛇身的长度初值
var GameOver:Boolean = false;
//标志游戏是否结束的标记
//========== 创建食物的函数 ==========

createfood();
function createfood() {
_root.attachMovie("block", "food", 0, {_width:7, _height:7});
//食物的深度永远为0,这样省去了删除被吃掉的食物的操作
new Color(food).setRGB(0xff0000);

//食物为红色的block
var Colum:Number = stagew/Move;
var Row:Number = stageh/Move;
//Colum为总列数,Row为总行数
food._x = random(Colum)*Move;
food._y = random(Row)*Move;
//食物随机出现的位置(移动距离的倍数)
}
//========== 主函数 ==========
_root.onEnterFrame = function() {
switch (NowKey) {
  //根据方向键值决定蛇头的移动方向
case 0 :
  head._x -= Move;
  break;
case 1 :
  head._y -= Move;
  break;
case 2 :
  head._x += Move;
  break;
case 3 :
  head._y += Move;
}
if (head._x<0 || head._x>stagew || head._y<0 || head._y>stageh) {
  GameOver = true;
  //头部出界则游戏结束
}
if (head.hitTest(food)) {
  createfood();
  //头部与食物接触后,调用新的食物
  for (var i = 1; i<=5; i++) {
   _root.attachMovie("block", "body"+(body+i), body+i, {_width:7, _height:7, _x:-50, _y:-50});
   //同时,蛇的身长增加5个单位,初始大小 7 ,初始位置在场景外
  }
  body += 5;
  txt.text = "分数 "+body;
}
for (var i = body; i>0; i--) {
  if (head.hitTest(this["body"+i])) {
   GameOver = true;
   //判断蛇体是否与头部接触,如果是游戏结束
  }
  if (i == 1) {
   this["body"+i]._x = head._x;
   this["body"+i]._y = head._y;
  } else {
   this["body"+i]._x = this["body"+(i-1)]._x;
   this["body"+i]._y = this["body"+(i-1)]._y;
  }
  //这个循环从尾至头各向前移动一个单位,与蛇头最近的身体与蛇头重合

}
if (GameOver) {
  //标志位GameOver为真时,显示游戏结束,删除onEnterFrame,移动停止
  txt.text = "游戏结束";
  delete this.onEnterFrame;
}
};

Flash 充电1: mc.attachMovie()
作用: 从库中复制影片剪辑

语法:
mc.attachMovie(id:String, name:String, depth:Number, [initObject:Object])
mc:MovieClip - 为该影片的父级影片
id:String - 库元件的链接名称;
name:String - 该影片剪辑实例的唯一名称;
depth:Number - 指定 SWF 文件所放位置的深度级别;
initObject:Object [可选] - 影片剪辑的属性的对象。

例如: 在库中有一元件标识符为"block"
_root.createEmptyMovieClip("MC", -1);
for (var i = 0; i<10; i++) {
MC.attachMovie("block", "b"+i, i, {_width:30, _height:30, _x:i*30, _y:10});
}
trace(MC["b"+0]._parent);
//被复制出的影片剪辑的父级影片为MC
trace(MC["b"+0]._parent._parent);
//被复制出的影片剪辑的父级影片的父级影片为_root


Flash 充电2: mc.duplicateMovieClip()
作用: 复制舞台上的影片剪辑

语法:
mc.duplicateMovieClip(name:String, depth:Number, [initObject:Object])
mc:MovieClip - 被复制的对象
name:String - 该影片剪辑实例的唯一名称;
depth:Number - 指定 SWF 文件所放位置的深度级别;
initObject:Object [可选] - 影片剪辑的属性的对象。

例如: 舞台中有一影片剪辑实例名为"MC"
for (var i = 0; i<10; i++) {
MC.duplicateMovieClip("M"+i, i, {_width:30, _height:30, _x:i*30, _y:10});
}

Flash 充电3: 影片剪辑的删除
注意:在删除时要区分复制的影片剪辑和非复制的影片剪辑
      对于复制的影片剪辑使用 removeMovieClip(target:Object)
      对于非复制的影片剪辑使用 unloadMovie(target:Object)
复制的影片剪辑: 指用duplicateMovieClip()、MovieClip.duplicateMovieClip()、MovieClip.createEmptyMovieClip()

或 MovieClip.attachMovie() 创建的影片剪辑实例。
非复制的影片剪辑: 指一开始就存在于舞台上的影片剪辑,即不是使用代码复制出来的影片。

教程到此结束
QQ:147461195(FL基理大师)

 

6。[Flash基础理论课15] 绚酷鼠标 [目标移动]
本次课中我们将演示三种鼠标跟随效果的实例

在学习之前,我们先复习一下前面(功能代码07<百变图>)曾用过的
目标移动公式:

mc.当前坐标 += (mc.目标坐标 - mc.当前坐标) * A 缓动常量(0<A<1)


例如:

舞台上有一个影片剪辑,实例名为 mc,使其移动到 x=400, y=300 的位置
mc.Tox = 400;
mc.Toy = 300;
mc.onEnterFrame = function() {
  this._x += (this.Tox-this._x)*0.3;
  this._y += (this.Toy-this._y)*0.3;
//更新每个实例的坐标了,可理解为:
//实例的 X 坐标 = 自己的X坐标 +(目标的X坐标–自己的X坐标)*0.3
//实例的 Y 坐标 = 自己的Y坐标 +(目标的Y坐标–自己的Y坐标) *0.3
};

实例一

思路:
1.复制出Num个鼠标,鼠标的透明度递减(如果i是递增的,N-i 就是递减的);
2.用第Num鼠标作为当前鼠标,其它均为跟随;
3.跟随的原理就是以前一个鼠标位置作为目标坐标,使后一个鼠标向前一个的位置移动。

步骤1:

CoolMouse1.jpg

     绘制一个鼠标,保存为影片剪辑,连接—>导出—>标志符"mouse"
步骤2:
加入AS代码:
Mouse.hide();
//隐藏原有鼠标
var Num = 10;
//鼠标跟随的数量
for (var i = 0; i<Num ; i++){
_root.attachMovie("mouse", "m"+i, i);
//复制出Num个鼠标的影片剪辑
this["m"+i]._alpha = (Num-i)/Num*100;
//设置出渐隐效果,每个鼠标的透明度递减
}
_root.onEnterFrame = function() {
this["m"+0]._x = _xmouse;
this["m"+0]._y = _ymouse;
//让this["m"+0]作为当前鼠标
for (var i = 1; i<Num ; i++){
  this["m"+i]._x += ((this["m"+(i-1)]._x)-this["m"+i]._x)*0.5;
  this["m"+i]._y += ((this["m"+(i-1)]._y)-this["m"+i]._y)*0.5;
}
//令后一个鼠标跟随前一个鼠标的位置,缓动地向前一个鼠标接近
};

实例二

思路:
1.方法与实例一类似;
2.改变了鼠标跟随的样式;
3.使小的鼠标透明度大,大的鼠标透明度小(如果i是递增的,N-i 就是递减的)。

步骤1:

CoolMouse1.jpg

     绘制一个鼠标,保存为影片剪辑,连接—>导出—>标志符"mouse"
步骤2:
加入AS代码:
Mouse.hide();
//隐藏原有鼠标
var Num = 10;
//鼠标跟随的数量
for (var i = 0; i<Num ; i++){
_root.attachMovie("mouse", "m"+i, i);
this["m"+i]._xscale = this["m"+i]._yscale=i/Num*100;
//鼠标的尺寸递增
this["m"+i]._alpha = (Num-i)/Num*100;
//鼠标的透明度递减
}
_root.onEnterFrame = function() {
this["m"+0]._x = _xmouse;
this["m"+0]._y = _ymouse;
for (var i = 1; i<Num ; i++){
  this["m"+i]._x += ((this["m"+(i-1)]._x)-this["m"+i]._x)*0.5;
  this["m"+i]._y += ((this["m"+(i-1)]._y)-this["m"+i]._y)*0.5;
}
};

实例三

思路:
1.方法与实例一类似;
2.改变了鼠标跟随的样式,也是使鼠标跟随围成一个圆的关键;
3.改变每个鼠标的旋转。

步骤1:

CoolMouse1.jpg

     绘制一个鼠标,保存为影片剪辑,连接—>导出—>标志符"mouse"
     注意:鼠标与注册点之间要留有一定的距离,这是使之围成圆的关键
步骤2:
加入AS代码:
var Num = 30;
//鼠标跟随的数量
for (var i = 0; i<Num ; i++){
_root.attachMovie("mouse", "m"+i, i);
this["m"+i]._rotation = i*24;
//设置初始的旋转角度
this["m"+i]._alpha = (Num-i)/Num*100;
}
_root.onEnterFrame = function() {
this["m"+0]._x = _xmouse;
this["m"+0]._y = _ymouse;
this["m"+0]._rotation += 10;
for (var i = 1; i<Num ; i++){
  this["m"+i]._x += ((this["m"+(i-1)]._x)-this["m"+i]._x)*0.5;
  this["m"+i]._y += ((this["m"+(i-1)]._y)-this["m"+i]._y)*0.5;
  this["m"+i]._rotation += 10;
  //使所有鼠标都转起来
}
};

Flash 充电: for 循环实现数组反向存储
var Len = 20;
//数组长度
var A:Array = new Array(Len);
for (var i = 0; i<Len ; i++){
A [I]= Len-i;
//A[Len-i-1] = i;
}
trace(A);

教程到此结束QQ:147461195(FL基理大师)

 


7。[Flash基础理论课14] 制作Loading [Loading]
思路:
1.制作一个100帧的读取动画,这样可以做出各式各样的Loading效果;
2.读取的百分比(percent) = 已读取字节数 / 总字节数 *100;
3.根据读取的百分比数(percent)停止到影片剪辑(Loading)的相应帧上。

 

步骤1:
制作一个100帧的Loading动画,保存为影片剪辑,放在舞台中,实例名为Loading
步骤2:
在第一帧加入AS代码
stop();
_root.onEnterFrame = function() {
var percent = Math.floor(getBytesLoaded()/getBytesTotal()*100);
//变量percent保存读取的百分比数
loading.gotoAndStop(percent);
//停止到影片剪辑 Loading 的相应帧上
if (percent == 100) {
  _root.play();
  //percent=100时,说明读取完毕,整个动画开始播放
}
};

 

Flash 充电1: getBytesLoaded()和getBytesTotal()

getBytesLoaded():获取已读取的字节数

getBytesTotal(): 获取整个SWF文件的全部字节数

 

Flash 充电2: 如何测试制作的Loading是否成功

load.jpg

1.测试Loading必需在测试影片(Ctrl+Enter)时才能使用;

2.我们可以在第2帧后导入2张稍大些的图片来占用字节数;

3.测试影片(Ctrl+Enter)后,在窗口中选择视图—>下载设置—>DSL;

4.在窗口中选择视图—>模拟下载(Ctrl+Enter)。


教程到此结束
QQ:147461195(FL基理大师)

 

9。[AS 功能代码教程12] 填色游戏 [FL基础理论大师]
在本次课程中我们将学习使用 Color 类来制作一个填色游戏
并通过本实例复习 for...in 及 SharedObject 的应用

思路:
1.使用脚本代码创建一个调色盘,鼠标点击色块后进行取色;
2.绘制作为填充的影片剪辑并把每一部都存为影片剪辑。例如: 填充对象是一个人物,那么要把他的头发,眼睛,脸等部

分都保存成影片剪辑;
3.最后把各部分影片再统一保存到一个影片剪辑(mc)中;
4.为了保存和读取mc中各影片中的颜色,所以要加入两个按钮 save_btn 和 load_btn 。

 

步骤1:
    绘制作为填充的影片剪辑并把每一部都存为影片剪辑;
    最后把各部分影片统一保存到一个影片剪辑中,实例名mc;
    绘制两个按钮实例名分别为 save_btn 和 load_btn 。
步骤2:
加入AS代码
//===== 绘制一个正方形作为色块以备调用 =====
_root.createEmptyMovieClip("box", -1);
var box_size:Number = 12;
var TheCol = 0x0;
//用于存储所取的色彩值
with (box) {
beginFill(TheCol);
moveTo(0, 0);
lineTo(box_size, 0);
lineTo(box_size, box_size);
lineTo(0, box_size);
lineTo(0, 0);
endFill();
}
box._visible = false;
//============================================
//************* 下面生成一个调色盘 *************
var panex:Number = 3;
var paney:Number = 3;
var column:Number = 18;
//起点 x 坐标为 3, 起点 y 坐标为 3, 总行数为 18
var i = 0;
for (var r = 0; r<=0xFF; r += 0x33) {
for (var g = 0; g<=0xFF; g += 0x33) {
  for (var b = 0; b<=0xFF; b += 0x33) {
   var p:MovieClip = box.duplicateMovieClip("box"+i, i);
   new Color(p).setRGB(r*256*256+g*256+b);
    //new Color(p).setRGB(r << 16 | g << 8 | b);
    //RGB转换公式,以上两种都可以使用
   p._x = panex + Math.floor(i/column)*(box_size+1);
   p._y = paney + i%column*(box_size+1);
//设置每个色块的坐标 行坐标: [i/column], 列坐标: i%column
   p.onRelease = function() {
    TheCol = new Color(this).getRGB();
    new Color(curser.BG).setRGB(TheCol);
   //点击到该色块后进行取色于保存到TheCol变量中
   };
   i++;
  }
}
}
//******************************************
//===== 判断点击到图案上以后对哪个影片剪辑填色 =====
mc.onRelease = function() {
var flag:Boolean = true;
//增加一个flag为了避免一次对多个影片进行填色
for (var k in mc) {
  if (mc[k].hitTest(_xmouse, _ymouse, true) && flag) {
   new Color(mc[k]).setRGB(TheCol);
   flag = false;
  }
}
};
//============================================
//************* 对mc中所有填充色的读取和保存 *************
save_btn.onRelease = function() {
var so:SharedObject = SharedObject.getLocal("Color_save");
for (var k in mc) {
  so.data[k] = new Color(mc[k]).getRGB();
}
};
load_btn.onRelease = function() {
var so:SharedObject = SharedObject.getLocal("Color_save");
for (var k in mc) {
  new Color(mc[k]).setRGB(so.data[k]);
}
};
//******************************************

 

Flash充电: 例举 Color 类中常用方法简介
请注意: 我们在舞台中所绘制出的影片剪辑即使给他是填充了纯色影片,使用getRGB()也不会取得其RGB值。我们只有对

其使用过setColor()后,才能用getRGB()获取该影片的颜色值。

 

例1: 为影片剪辑 mc 创建一个名为 m_Col 的 Color 对象,并将其RGB值设置为橙色:
var my_color:Color = new Color(my_mc);
my_color.setRGB(0xff9933);

 

例2: 获取影片剪辑 mc 的RGB值并以16进制显示出来:
var m_Col:Color = new Color(mc);
m_Col.setRGB(0xff9933);
var myValue:String = m_Col.getRGB().toString(16);


教程到此结束
QQ:147461195(FL基理大师)

 

10。[Flash基础理论课13] FL记事本 [SharedObject]
SharedObject(本地共享对象)功能类似于网页中的Cookie

允许设计者存储少量信息在客户端

思路:

1.用脚本创建出两个文本框和两个按钮;

2.两个文本框分别为 title_txt 和 content_txt 用于输入及显示信息;
3.两个按钮分别为 save_btn:保存文本内容,load_btn:读取文本内容。

 

 

在第一帧中加入以下代码:
//====================创建两个文本框====================
//创建及设置标题文本框
var t_f:TextFormat = new TextFormat();
t_f.size = 20;
_root.createTextField("title_txt", 1, 10, 10, 150, 25);
with (title_txt) {
border = true;
borderColor = 0x0;
type = "input";
setNewTextFormat(t_f);
}
//创建及设置内容文本框
_root.createTextField("content_txt", 2, 10, 40, 150, 150);
with (content_txt) {
border = true;
borderColor = 0x0;
type = "input";
wordWrap = true;
setNewTextFormat(t_f);
}

//====================创建两个按钮====================
//存储按钮
_root.createEmptyMovieClip("save_btn", 3);
save_btn.createTextField("txt", 0, 0, 0, 40, 20);
save_btn.txt.text = "Save";
save_btn._x = 50;
save_btn._y = 200;
save_btn.onRelease = function() {
var so:SharedObject = SharedObject.getLocal("log_save");
//与本地共享对象进行连接,注意这是个静态方法
so.data.title_txt = title_txt.text;
so.data.content_txt = content_txt.text;
//存储标题及内容信息为log_save的数据
};
//读取按钮
_root.createEmptyMovieClip("load_btn", 4);
load_btn.createTextField("txt", 0, 0, 0, 40, 20);
load_btn.txt.text = "Load";
load_btn._x = 100;
load_btn._y = 200;
load_btn.onRelease = function() {
var so:SharedObject = SharedObject.getLocal("log_save");
//与本地共享对象进行连接,注意这是个静态方法
title_txt.text = so.data.title_txt;
content_txt.text = so.data.content_txt;
//将log_save的数据读取到标题及内容文本框中,这两句与存储操作正好相反
};

 

 

Flash充电: SharedObject 概念及常用方法简介
1.SharedObject 作用: 将共享对象永久贮存在用户计算机上。在Flash中我们可用来实现如用户登陆,保存日记,甚至游

戏存盘等功能。

 

2.SharedObject 引用(getLocal):

请注意getLocal()方法为静态方法,声明方法如下:
var so:SharedObject = SharedObject.getLocal("kookie");

 

3.SharedObject 存储(data): 下面示例实现一个简单的个人信息的存储
var my_so:SharedObject = SharedObject.getLocal("savedData");
my_so.data.name = "Alan"
my_so.data.sex = "male"
my_so.data.age = "21"

 

4.SharedObject 部分读取(data): 下面示例实现个人信息的读取
var my_so:SharedObject = SharedObject.getLocal("savedData");
trace(my_so.data.name)
trace(my_so.data.sex)
trace(my_so.data.age)

 

5.SharedObject 全部读取(data): 结合 for...in 语句读取所有属性对象
var my_so:SharedObject = SharedObject.getLocal("savedData");
for (var prop in my_so.data) {
    trace(prop+": "+my_so.data[prop]);
}

 

6.SharedObject 清除数据(clear):
var my_so:SharedObject = SharedObject.getLocal("savedData");
my_so.clear();


教程到此结束
QQ:147461195(FL基理大师)

 

第一章  AS3的一些优化计算方法
来源:John Grden Blog

1.用乘法来代替除法(当除数可转化为有限数的时候)。比如var n:Number = value * 0.5;要比var n:Number = value

/ 2;快。但差别并不是很大。只有在需要大量计算情况下,比如3D引擎中差别才比较明显。

 

2.用位运算代替除2或乘2。比如10>>1要比10*2快,而10<<1要比10*2 快。从测试来看位运算几乎比乘除快一倍,但是一

般情况下,我们不能选择位运算,比如我们就不能用13>>1来代替13/2,尽管前者比后者运算速度更快,但2者的运算结果

却不一样。所以还是要看具体情况。

 

3.用unit()或int()代替取整运算Math.floor()和Math.ceil()。比如var test:uint = uint(1.5);要比var test:Number

= Math.floor(1.5);快;而var test:uint = uint(1.5)+1;要比var test:Number = Math.ceil(1.5);也快。如果是

Math.floor(),还可以用位运算(>>0)来代替。比如var test:uint =1.5>>0,比unit()或int()更快。

 

4.用乘-1来代替Math.abs()方法。比如var nn:Number = -23;var test:Number= nn < 0 ? nn * -1 : nn;要比var

nn:Number = -23;var test:Number = Math.abs(nn);快。

当然还有更多的优化计算的方法。一般来说,低级运算要比高级运算速度;内部方法比调用其他方法速度快。另外要注意

的是,这些方法有的时候可能并一定适用。

 


第二章  Actionscript 优化指南
来源 gotoAndStop.it

原著 Marco Lapi,alias Lapo, aw译

在这篇文章中,我们将讨论多种优化 Actionscript 代码的方法.
此外我们也针对一些典型的游戏代码进行了系列测试,来最大限度的发掘、提高Flash播放器的性能。

何时进行优化

对现有程序进行优化的过程,有时十分的冗长与困难,这与原始代码的非优化程度有关,所以在投入大量时间进行代码优

化之前,最重要的是要估计出要在什么地方对代码做出修改或替换。

一个游戏代码的最重要的部分就是主循环体,通常情况下该循环体要在flash的每一帧上执行,并控制游戏中的角色属性

和重要的数据参数。而对于主循环体以外的部分,也可能是次要循环部分,同样要注意是给其否分配了过多的资源,而没

有分配给那些更需要资源的核心部分。
通过积累在各处节约出来的时间(可能每处仅仅是几个毫秒),您会明显发现自己的swf运行得更加稳定,并且游戏感也大

大加强。

简洁与高效的代码

书写出十分简洁、可以再次调用的代码(有时可能是面向对象的)是一项精细的工作,但这需要多年的编程经验。对于OOP

(object oriented programming,面向对象的程序设计),有些场合根本利用不到它的优势,这使得它显得十分奢侈。在

有限的资源条件下(可能是flash播放器的原因),通过更先进的方法,像刚刚提到的OOP,就可能反而导致令人不满意的结

果。

我们并不是说OOP对游戏编程不好,只是在某些场合它显得过于奢侈和多余。毕竟有时候“传统的方法”却能得到更好的

结果。

大体而言,用OOP是比较好的,因为它让代码维护更加简单。但在后文中,你会看到有时为了充分发挥flashplayer性能,

而不采用OOP技术。例如:处理快速滚动或者计算十分复杂的数学问题。

基本的优化

一提及代码优化,我们马上会联想到执行速度的改进,而很少去考虑系统资源的分配。这是因为当今,即使是将被淘汰的

计算机,都有足够的内存来运行我们大部分的flash游戏(128M的内存足以满足大多数情况的需要,况且,512M的内存是当

今新电脑的基本配置)

变量

在各种重要的代码优化手段中,有这么一条:在定义局部变量的时候,一定要用关键字var来定义,因为在Flash播放器中

,局部变量的运行速度更快,而且在他们的作用域外是不耗占系统资源的。

aw附:var变量仅仅在花括号对中才有“生命”,个人认为没有系统学过编程的人容易出错的一个地方:

awMC.onLoad = function(){
  var aw = 1;
}
awMC.onEnterFrame = function(){
//不存在aw这个变量
}
一段非优化代码:

function doSomething()
{
mx = 100
my = 100
ar = new Array()

for (y=0; y < my; y++)
{
  for (x=0; x < mx; x++)
  {
   i = (y * mx) + x
   arr[i] = i  
  }
}

return arr
}

这段代码中,并未声明函数体内的那些变量(那些仅仅在函数内使用的变量)为局部变量,这使得这些变量被播放器调用的

速度更慢,并且在函数执行完毕的时候仍然耗占系统资源。

下面列出的是经过改进的同样功能的代码:

function doSomething()
{
var mx = 100
var my = 100
var ar = new Array()

for (var y=0; y < my; y++)
{
  for (var x=0; x < mx; x++)
  {
   var i = (y * mx) + x
   arr[i] = i  
  }
}
return arr
}
这样一来所有的变量均被定义为了局部变量,他们能够更快地被播放器调用。这一点在函数大量(10,000次)循环运行时

显得尤为重要!当一个函数调用结束的时候,相应的局部变量都会被销毁,并且释放出他们占有的系统资源。

 

onEnterFrame 事件

onEnterFrame事件对于游戏开发者而言是非常有用的,它使得我们能够快速、反复地按照预设帧频(fps)运行一段程序。

回想在Flash5的时代,这(onEnterFrame实时监控)是一种非常流行的技术,用这样的事件来控制机器游戏对手的逻辑,又

或者我们可以在每一个子弹上设置这样的事件来监测子弹的碰撞。

实际上,我们并不推荐给过多的MoveClip添加这样的事件,因为这样做会导致“无头绪码(spaghetti code)”的出现,并

且容易导致程序效率明显降低。

大多数情况下,用单独一个onEnterFrame事件就可以解决问题了:用这一个主循环来执行你所需要的操作。

另一个简单的办法是设置一个合适的帧频:要知道帧频越高,CPU资源就越紧张。

在帧频为25-35(fps)之间时,onEnterFrame足以很好地执行较复杂代码,哪怕你的计算机配置较低。因此,在没有特殊要

求的场合,我们不推荐使用高于60(fps)的帧频。

 

矢量图与位图

在处理图形前,我们一定要做出正确的选择。Flash能对矢量图和位图进行完美的兼容,然而矢量图和位图在播放器中的

表现实质却完全不同。

在用到矢量图的时候,我们要尽可能简化它们的形状,去除多余的端点。这样做将大大降低播放器用于呈现矢量图所要进

行的计算量。另一个重要方面在于线条的运用,尽量减少和避免冗陈的线条结构,因为它们会直接影响到flash的播放效

率。

当某个实例透明度小于100时,也会对播放速率造成影响,所以如果你发现自己的Flash播放速率过慢,就去挑出这些透明

的实例来吧!

那么,如果真的需要呈现比较复杂的场景时,你就最好考虑使用位图实现。虽然Flash在对位图的渲染效率上并不是最优

越的(比如和Flash的“兄长” Director比起来),但丰富的视觉内容呈现只能靠位图(与位图同复杂度的矢量图形渲染速

率非常低)了,这也是很多基于区块的游戏中广泛采用像素图作为背景的原因。顺便要提到的是,Flash虽然对GIF,JPG和

PNG都有所支持,但是渲染速度上PNG还是占有绝对优势,所以我们建议flash中的位图都尽可能采用PNG格式。

影片剪辑(MovieClip)的可视性[下面将MovieClip简称为mc]

您可能会经常碰到这样一种情况:有大量不可见/屏幕外的mc等待出场(比如游戏中屏幕外的地图、人物等等)。
要知道,播放器仍然要消耗一定的资源来处理这些不可见/屏幕外的mc,哪怕他们是单帧,非播放的状态。

最好的解决办法之一是给这些mc一个空白帧,当他们不出现在屏幕上时,你能用gotoAndStop()语句跳转到这一帧,从而

减少播放器对资源的需求。

请务必记住,这种情况下,简单的设置可见度属性为不可见( _visible = false )是无效的,播放器将继续按照这些mc所

停留或播放的帧的复杂度来分配资源。


数组
数组在各种需要记录数据的应用程序和游戏中都被广泛的使用。

一个典型的例子就是基于区块的Flash游戏,在这样一类的游戏中,地图有时被存放成形如arr[y][x]的二维数组。虽然这

是一种很常见的方法,但是如果用一维数组的话,却能提高程序的运行效率。另一个重要的方法来提高数组效率是在数组

遍历的时候使用for in 循环来代替传统的 for 或者while循环语法。
例如:

一段代码如下
for (var i in arr)
{
if (arr[i] > 50)
{
  // 进行某些操作
}
}

它的执行速度明显高于这一段代码:
for (var i=0; i<10000; i++)
{
if (arr[i] > 50)
{
  // 进行某些操作
}
}
前者的效率比后者提高了30%,这个数字在你的游戏要逐帧执行这一段代码的时候显得更加宝贵!

高级优化:
1) for循环 和 while循环
用while循环将会得到比for循环更好的效率。然而,从数组中读取数据,用for in循环式最好的选择!

所以我们不推荐使用:
for (var i=0; i<1000; i++)
{
//进行某些操作
}而推荐使用

var i=-1
while (++i < 1000)
{
//进行某些操作
}

 

2) 从数组中读取数据
我们通过测试发现,for in循环的效率大大高于其他的循环方式。参看:
arr = []
MAX = 5000

//数组赋值
for (i=0; i < MAX; i++)
{
arr[i] = i
}
var item = null

// For Loop
for (var i=0; i < MAX; i++)
{
item = arr[i]
}

//For循环
for (var i in arr)
{
item = arr[i]
}


// While循环
i = -1
while(++i < MAX)
{
item = arr[i]
}

 

3) 向数组中写入数据(while , for)
可以看到while循环稍占优势。

 

4) _global(全局)变量同Timeline(时间轴)变量
我们猜测采用全局变量能提高变量调用速度,然而效果并不像预计的那样明显。

 

5) 单行、多行变量赋值
我们发现单行变量赋值效率大大高于多行。比如:
a = 0
b = 0
c = 0
d = 100
e = 100

效率就不如:
a = b = c = 0
d = e = 100

 

6) 变量名寻址
这个测试反映了变量名的预寻址是非常重要的,尤其是在循环的时候,一定要先给丁一个指向。这样大大节约了寻址时间

比如:
var num = null
t = getTimer()
for (var i=0; i < MAX; i++)
{
num = Math.floor(MAX) - Math.ceil(MAX)
}
t1.text = "Always lookup: " + (getTimer() - t)

就不如:
t = getTimer()
var floor = Math.floor
var ceil  = Math.ceil
for (var i=0; i < MAX; i++)
{
num = floor(MAX) - ceil(MAX)
}

 

7) 短变量名和长变量名
变量名越短,效率越高。考虑到长变量名也有它的好处(比如,便于维护等),因此建议在关键部位(比如大量循环出现

的时候)使用短变量名,最好就1-2个字符。

 

8) 循环前、后声明变量
在测试前,我们认为循环前声明变量会更加节约时间,不料测试结果并不明显,甚至还恰恰相反!

// 内部声明
t = getTimer()
for (var i=0; i < MAX; i++)
{
var test1 = i
}
t1.text = "Inside:" + (getTimer() - t)

// 外部声明
t = getTimer()
var test2
for (var i=0; i < MAX; i++)
{
test2 = i
}

 

9) 使用嵌套的if结构
当用到复杂的条件表达式时。把他们打散成为嵌套的独立判断结构是最佳方案。下面的代码我们进行了测试,发现这种效

果改进明显!
MAX = 20000
a = 1
b = 2
c = -3
d = 4

var i=MAX
while(--i > -1)
{
if (a == 1 && b == 2 && c == 3 && d == 4)
{
  var k = d * c * b * a
}
}

//下面的判断更加节省时间
var i=MAX
while(--i > -1)
{
if (a == 1)
{
  if (b == 2)
  {
   if (c == 3)
   {
    if (d == 4)
    {
     var k = d * c * b * a
    }
   }
  }
}
}

 

10) 寻找局部变量(this方法同with方法比较)
局部变量的定位方法很多。我们发现用with比用this更加有优势!
obj = {}
obj.a = 1
obj.b = 2
obj.c = 3
obj.d = 4
obj.e = 5
obj.f = 6
obj.g = 7
obj.h = 8
obj.test1 = useThis
obj.test2 = useWith
MAX = 10000
function useThis()
{
var i = MAX
while(--i > -1)
{
  this.a = 1
  this.b = 2
  this.c = 3
  this.d = 4
  this.e = 5
  this.f = 6
  this.g = 7
  this.h = 8
}
}
function useWith()
{
var i = MAX
while(--i > -1)
{
  with(this)
  {
   a = 1
   b = 2
   c = 3
   d = 4
   e = 5
   f = 6
   g = 7
   h = 8
  }
}
}

 

11) 循环监听键盘事件
同刚才所提到的寻址一样,我们实现给一个指向会得到更好的效率,比如:
keyDown = Key.isDown
keyLeft = Key.LEFT

//我们再用 if (keyDown(keyLeft))
附:我们测试了按键代码和键值常量的效率发现并无太大差别。

 

12) Math.floor()方法与int()
这个问题曾在Flashkit的论坛被提出讨论过。测试表明,旧的int方法反而效率更高。我们的测试结果也反映了这一点。

 

13)eval表达式与中括号语法
我们并没有发现明显的差别,并不像刚才所述那样,旧的eval表达式比起中括号方法并没有太大的优势
var mc = eval("_root.myMc" + i)
var mc = _root["myMc" + i]
//两者效率差不多16) 涉及MC的循环:ASBroadcaster 同欢同循环的差别

结论
我们从这些测试结果中发现,对于不同的需求,采用不同的代码,我们可以大大提高脚本的执行效率。虽然我们在这里罗

列了许多的优化代码的方法,需要大家自己测试、实验的还有很多(考虑到每个人的需求不同).如果你想更加深入地讨论

这类问题。可以来我们的论坛。

aw附:
终于翻译完了,自己也学到很多好东西,大家又什么问题可以去gotoAndPlay的官方,也可以来我的Blog提出!


第三章  黑羽AS心得:浅释ActionScript的代码优化
来源:Kingda blog

本文既为浅谈代码优化,那么就不深入到OOP设计层面。仅涉及Flash8帮助里面提到的一些代码编写优化原则,并加以解

释。
准则来源于Flash8 帮助,我做了一些解释:


1.避免从一个循环中多次调用一个函数。
在循环中包含小函数的内容,可使效果更佳。小函数生命期短,利于资源释放。尤其是在大的循环中时。


2.尽可能使用本机函数。
本机函数要比用户定义的函数运行速度更快。本机函数即Flash中内有的一些函数(intrinsic),比如hitTest(),你没必

要自己写一个类似的。


3.不要过多使用 Object 类型。
数据类型注释应力求精确,这样可以提高性能。只有在没有适当的备选数据类型时,才使用 Object 类型。同时也便于代

码管理,时刻知道对象的类型和作用。
同时也有利于编译器编译时优化。


4.避免使用 eval() 函数或数据访问运算符。
通常,较为可取且更有效的做法是只设置一次局部引用。不得已时才用eval,比如转换_droptarget为MovieClip时。


5.在开始循环前将 Array.length 赋予变量,尤其是大的循环。
在开始循环前将 Array.length 赋予变量(比如var iLength:Number),将其作为条件使用,而不是使用 myArr.length 本

身。
原因,在循环中,iLength是Number变量,会被放入寄存器使用,效率远比访问Array再得到length高。例如,应使用

var fontArr:Array = TextField.getFontList();
var arrayLen:Number = fontArr.length;
for (var i:Number = 0; i < arrayLen; i++) {
    trace(fontArr[i]);
}

来代替:
var fontArr:Array = TextField.getFontList();
for (var i:Number = 0; i < fontArr.length; i++) {
    trace(fontArr[i]);
}

 

6.注重优化循环及所有重复动作。
Flash Player 花费许多时间来处理循环(如使用 setInterval() 函数的循环)。


7.在局部变量够用时,不要使用全局变量。类静态变量也要少用。
全局变量是开发者的恶梦。实在需要全局变量的话,我建议使用singleton设计模式来进行管理。


8.声明变量时,添加 var 关键字。
这是为了编译时让编译器知道你的变量类型,优化编译。


黑羽补充一点:对关键字的使用要谨慎。
不赞成使用关键字作为自己的method和属性名,除非你确认后续开发不会用到相同的事件名和属性名。
但你怎么知道flash使用了多少隐藏关键字?太多了!比如说 className, invalidate, refresh, mouseOver等等不常用

的关键词。好的方法是使用SEPY编辑器来写代码,那里面加亮了所有公布的和没有公布的关键词。
而且因为很有可能和start,load,等这些常用的事件名重复,带来代码不必要的修改和麻烦。


9.对涉及到调用绘图资源的函数时,尽量先多判断再调用。
所有渐变,位置变化,创建删除MC,组件等函数都涉及到绘图资源的调用。在很多情况下,尽量先用逻辑判断变量或者对

象的属性,必要时再调用这些函数。这样可以节省较多的计算资源。


这是我们经常会在浏览网页和论坛时看到的图片转场效果

制作这些效果我们很自然会想到用setMask函数来完成

在本节中我们将介绍七种基本转场效果

思路:
1.注意共三张图片,一张是底版(pic_old)放在最底层,一张是切换来的新图

  (pic_new)放在中间层,最后还有一张用来做新图的遮罩层(mask);
2.新图和底版的深度不要颠倒,新图要比底版的深度高,否则会发生错误;
3.我们只在mask上面作文章,让mask去加载遮罩物,这样就可以完成许许多多不同的效果了。

 

步骤1:
(1)绘制一个正方形(50*50),注册点在中心,保存为影片剪辑

   连接—>导出—>标志符 Rec;

(2)绘制一个圆形(50*50),注册点在中心,保存为影片剪辑

   连接—>导出—>标志符 Cir;

(3)导入图片n张,均保存为影片剪辑,注册点在左上(0,0)
   这些图片的连接—>导出—>标志符 分别从 pic1, pic2, pic3 ... picn

 

步骤2:
加入AS代码
var old_p:String;
//临时变量用于存储当前图片
var n:Number = 0;
//变量n为当前所在图片
var Num:Number = 5;
//Num图片数量
//=======================================================
//鼠标点击后设置底版图、新图和遮罩层,并调用(PassEffect)
_root.onMouseDown = function() {
n = n < Num ? ++n : 1 ;

_root.createEmptyMovieClip("pic_old", -3);
pic_old.attachMovie(old_p, old_p, 1);
old_p = "pic"+n;
_root.createEmptyMovieClip("pic_new", -2);
pic_new.attachMovie("pic"+n, pic, 1);
_root.createEmptyMovieClip("mask", -1);
pic_new[pic].setMask(mask);
//在测试时,可以把setMask这句注释掉,可更好地观察遮罩层的情况
PassEffect();
};


//============================================================

function PassEffect() {
switch (1+Math.floor(Math.random()*7)) {
  //***************效果1[见附录]***************
  //复制若干个圆,分布在每行每列,并使每个圆的大小不断增加至覆盖整张图
case 1 :
  for (i=0; i<7; i++) {
   for (j=0; j<6; j++) {
    var p:MovieClip = mask.attachMovie("Cir", "Cir"+i*10+j,

i*10+j);
  //注意这里是mask.attachMovie(),加载来的图形都属于遮罩层(mask)
    p._width = 20;
    p._height = 20;
    p._x = 20+i*60;
    p._y = 20+j*60;
    p.onEnterFrame = function() {
     if (this._width<180) {
      this._width = this._height += 8;
     } else {
      delete this.onEnterFrame;
     }
    };
   }
  }
  break;
//=================================================================
  //***************效果2[见附录]***************
  //复制一个正方形,放入舞台中心,设置他其初始大小为10*10,并放大
case 2 :
  var p:MovieClip = mask.attachMovie("Rec", Rec, 1);
  p._width = 10;
  p._height = 10;
  p._x = Stage.width/2;
  p._y = Stage.height/2;
  p.onEnterFrame = function() {
   if (this._width
    this._width += 40;
    this._height += 40;
   } else {
    delete this.onEnterFrame;
   }
  };
  break;
//=================================================================
  //***************效果3[见附录]****************
//复制一个正方形,其初始大小比舞台的尺寸多一些,使其移动到舞台中心
case 3 :
  var p:MovieClip = mask.attachMovie("Rec", "Rec"+1, 1);
  p._width = Stage.width+10;
  p._height = Stage.height+10;
  p._x = 0-p._width;
  p._y = 0-p._height;
  p.onEnterFrame = function() {
   this._x += (Stage.width/2-this._x)*0.3;
   this._y += (Stage.height/2-this._y)*0.3;
  };
  break;
//=================================================================
  //***************效果4[见附录]***************
  //复制二个正方形,放到舞台外的左右各一个,使它们都向舞台中心移动
case 4 :
  var p:MovieClip = mask.attachMovie("Rec", "Rec"+1, 1);
  p._width = Stage.width;
  p._height = Stage.height;
  p._x = -p._width/2;
  p._y = Stage.height/2;
  p.onEnterFrame = function() {
   if (this._x
    this._x += 15;
   } else {
    delete this.onEnterFrame;
   }
  };
  var p:MovieClip = mask.attachMovie("Rec", "Rec"+2, 2);
  p._width = Stage.width;
  p._height = Stage.height;
  p._x = Stage.width+p._width/2;
  p._y = Stage.height/2;
  p.onEnterFrame = function() {
   if (this._x>Stage.width/2) {
    this._x -= 15;
   } else {
    delete this.onEnterFrame;
   }
  };
  break;
//=================================================================
  //***************效果5[见附录]***************
//随机产生两种倾斜角度,用一个递增变量d_time来控制每个遮罩物的开始时间
case 5 :
  if (Math.random()<=0.5) {
   var rotation = 45;
  } else {
   var rotation = -45;
  }
  for (i=-10, d_time=0; i<30; i++, d_time++) {
   var p:MovieClip = mask.attachMovie("Rec", "Rec"+d_time, d_time);
   p._width = 0;
   p._height = Stage.height*2;
   p._x = p._width/2+i*20;
   p._y = Stage.height/2;
   p._rotation = rotation;
   p.delay = d_time;
   p.start_time = 0;
   p.onEnterFrame = function() {
    if (this.start_time
     this.start_time += 3;
    } else if (this._xscale<30) {
     this._xscale += 2;
    } else {
     delete this.onEnterFrame;
    }
   };
  }
  break;
//=================================================================

   //***************效果6[见附录]***************
  //与效果5相近,但在遮罩物的尺寸及位置上要略加改动
case 6 :
  if (Math.random()<=0.5) {
   for (i=0; i<45; i++) {
    var p:MovieClip = mask.attachMovie("Rec", "Rec"+i, i);
    p._width = 0;
    p._height = Stage.height+10;
    p._x = i*10;
    p._y = Stage.height/2;
    p.delay = i;
    p.start_time = 0;
    p.onEnterFrame = function() {
     if (this.start_time
      this.start_time += 3;
     } else if (this._xscale<30) {
      this._xscale += 2;
     } else {
      delete this.onEnterFrame;
     }
    };
   }
  } else {
   for (i=0; i<35; i++) {
    var p:MovieClip = mask.attachMovie("Rec", "Rec"+i, i);
    p._width = Stage.width+10;
    p._height = 0;
    p._x = Stage.width/2;
    p._y = i*10;
    p.delay = i;
    p.start_time = 0;
    p.onEnterFrame = function() {
     if (this.start_time
      this.start_time += 3;
     } else if (this._yscale<30) {
      this._yscale += 2;
     } else {
      delete this.onEnterFrame;
     }
    };
   }
  }
  break;
//=================================================================
  //***************效果7[见附录]***************
//复制长条,均放在舞台外的上方,并使Y坐标有所差异,向下运动
case 7 :
  for (i=0; i<40; i++) {
   var p:MovieClip = mask.attachMovie("Rec", "Rec"+i, i);
   p._width = 10;
   p._height = Stage.height+50;
   p._x = p._width/2+i*p._width;
   p._y = -p._height+Math.random()*50;
   p.onEnterFrame = function() {
    if (this._y
     this._y += 20;
    } else {
     delete this.onEnterFrame;
    }
   };
  }
  break;
}
}


Flash充电1: MovieClip.setMask 方法
mc.setMask(mask:Object): 使参数 mask 中的影片剪辑成为 mc 的遮罩层。

Flash充电2: 条件运算符(三目运算) ? :
格式:expression1 ? expression2 : expression3
例如:
var x:Number = 5;
var y:Number = 10;
var z = (x < 6) ? x: y;
trace (z);
// returns 5
附录:
效果1:
效果2:
效果3:
效果4:
效果5:
效果6:
效果7:
教程到此结束
QQ:147461195(FL基理大师)


在本实例中只介绍倒计时的计算方法

至于本机存储,我们会在下次课专门讲到

 

思路:1.创建一个文本用于输出时间;
     2.实例化一个Date类,给定参数为倒计时时间;
     3.用倒计时时间减不断变化的新的系统时间求出相差的毫秒数;
     4.最后学会毫秒-秒-分钟-小时-天之间转换。

 

加入AS代码:
_root.createTextField("txt", 1, 150, 150, 0, 0);
txt.autoSize = true;
//创建一个文本框用于输出时间
var year = 2008;
var month = 8;
var date = 8;
var hour = 20;
var minute = 0;
var second = 0;
//设置定时时间(本例以北京奥运为倒计时)
var End:Date = new Date(year, month-1, date, hour, minute, second);
//Date类实例化将日期和时间指定为毫秒, 月份(0~11)所以要减1


_root.onEnterFrame = function () {

var Now:Date = new Date();
//获得当前的日期和时间(单位:毫秒)

 

var dif = (End-Now)/1000;
//计算出二者相差的毫秒数,除以1000转换为秒数

 

var dif_d = Math.floor(dif/(3600*24));
//相差的天数=[相差的总秒数/一天的总秒数(60秒*60分*24小时)]

 

var dif_h = Math.floor((dif-dif_d*3600*24)/3600);
//相差的小时=[(天数取整后剩于的总秒数)/一小时的总秒数]

 

var dif_m = Math.floor((dif-dif_d*3600*24-dif_h*3600)/60);
//相差的分钟=[(天数和小时取整后剩于的总秒数)/一分钟的总秒数]

 

var dif_s = Math.floor(dif-dif_d*3600*24-dif_h*3600-dif_m*60);
//相差的秒数=[天数和小时和分钟取整后剩于的总秒数]

 

txt.text = dif_d+"天 "+dif_h+"小时 "+dif_m+"分钟 "+dif_s+"秒";
};

 

Flash充电: Date类简介
1.Date类的构造函数
public Date([yearOrTimevalue:Number], [month:Number], [date:Number], [hour:Number],[minute:Number],

[second:Number], [millisecond:Number])

 

2.构造函数中的参数
yearOrTimevalue:Number [可选]: 如果指定了其它参数,则此数字表示年份(如 1965)。如果该数字表示

时间值(未指定任何其它参数),则为 1970 年 1月 1日 0:00:00 之前或之后的毫秒数。

month:Number [可选]: 0(一月)到 11(十二月)之间的整数。

date:Number [可选]: 1 到 31 之间的整数。

hour:Number [可选]: 0(午夜) 到 23(晚上11点)之间的整数。

minute:Number [可选]: 0 到 59 之间的整数。

second:Number [可选]: 0 到 59 之间的整数。

millisecond:Number [可选]: 0 到 999 之间的整数(毫秒)。

 

3.示例

例1:
var d1:Date = new Date();
//Date 对象被设置为运行赋值语句的时间。
trace(d1)
//返回: Tue Dec 18 22:35:38 GMT+0800 2007

 

例2:
var d2:Date = new Date(2000, 0, 1);
//使用传递 Date 对象的年份、月份和日期参数创建 Date 对象。

trace(d2)
//返回: Sat Jan 1 00:00:00 GMT+0800 2000

 

例3:
var d1:Date = new Date();
var d2:Date = new Date(2000, 0, 1);
var dif = d1-d2
trace(dif);
//返回相差的毫秒数: 251332873437

 

例4:也可以通过getTime()函数得到相同的结果
var d1:Date = new Date();
var d2:Date = new Date(2000, 0, 1);
var dif = d1.getTime()-d2.getTime();
trace(dif);
//返回相差的毫秒数: 251332873437


教程到此结束
QQ:147461195(FL基理大师)

 

每个程序员都应该在他的编程生涯中学习C语言。它的好处多到你不能忽视。不仅是因为它能带来很多工作机会,而且它

也从整体上让你认识电脑。

C比其他的编程语言 (C++, Java)更底层一点。在底层编程会使你从整体上更好的理解电脑。
设备驱动和操作系统都是专门用C写成的。现在你可以再也不用写一个设备驱动程序和操作系统了,但是如何你要修改一

个这样的程序你怎么办呢?
如果你想要找一份微控制器编程的工作你怎么办呢?它们是用C写的。你要放弃可能的工作机会,只是因为你不想学一门

新的语言吗?
C程序比其它任何语言产生的程序都要更小更快。有时候你的程序需要那一点点速度提升,只有C能给你。
如果你学过C,你能学其他任何现代编程语言。原因是,所有现代编程语言 (Java, C++, C#, 等)都是基于C的。
因为C已经发展了很多年,它有巨大的社区和集体代码基础。这能让你快速有效的实现先前已经编好的新算法和函数。

C是开源社区的语言。开源的榜样,Linux,是用C编写的。如果你了解C,你能参与和贡献到大量开源社区中去,比如

Source Forge。
C是唯一一门告诉你指针到底是什么的语言。C#和Java完全跳过了这个主题。指针赋与了C强大的能力。
C仍然是编程工作最普遍要求掌握的语言。在你的领域下绝对值得花去时间学C。
任何带有微处理器的东西都支持C。从你的微波炉到手机,C 提供了强大的技术动力。

 

一、概论
对于数据的处理工作,排序是其最基本的运算之一。在当今的计算机系统中,花费在排序上的时间占系统CPU运行时间的

很大比重。有资料表明,在一些商用计算机上,在排序上的CPU时间达到20%至60%。为了提高计算机的工作效率,人们

提出了各种各样的排序方法和算法。这些算法有力地发展、并充分地展示了算法设计的某些重要原则和高超技巧。因此,

对于计算专业人员来说掌握排序算法是十分重要的。

 

二、排序算法简介
本次课程中我们将介绍六种排序方法:插入排序,选择排序,冒泡排序,希尔排序,快速排序及二路归并。

 

<1>直接选择排序(Selection Sort):简单的选择排序,它的比较次数一定:n(n-1)/2。也因此无论在序列何种情况下,

它都不会有优秀的表现(从上100K的正序和反序数据可以发现它耗时相差不多,相差的只是数据移动时间),可见对数据

的有序性不敏感。它虽然比较次数多,但它的数据交换量却很少。所以我们将发现它在一般情况下将快于冒泡排序。

 

<2>直接插入排序(Insertion Sort):简单的插入排序,每次比较后最多移掉一个逆序,因此与冒泡排序的效率相同。但

它在速度上还是要高点,这是因为在冒泡排序下是进行值交换,而在插入排序下是值移动,所以直接插入排序将要优于冒

泡排序。直接插入法也是一种对数据的有序性非常敏感的一种算法。在有序情况下只需要经过n-1次比较,在最坏情况下

,将需要n(n-1)/2次比较。

 

<3>冒泡排序(Bubble Sort):将相邻的两个数据元素按关键字进行比较,如果反序,则交换。对于一个待排序的数据元素

序列,经一趟排序后最大值数据元素移到最大位置,其它值较大的数据元素向也最终位置移动,此过程为一次起泡。然后

对下面的记录重复上述过程直到过程中没有交换为止,则已完成对记录的排序。

 

<4>快速排序(Quick Sort):是冒泡排序的改进,它通过一次交换能消除多个逆序,这样可以减少逆序时所消耗的扫描和

数据交换次数。在最优情况下,它的排序时间复杂度为O(nlog2n)。即每次划分序列时,能均匀分成两个子串。但最差情

况下它的时间复杂度将是O(n^2)。即每次划分子串时,一串为空,另一串为m-1(程序中的100K正序和逆序就正是这样,

如果程序中采用每次取序列中部数据作为划分点,那将在正序和逆时达到最优)。从100K中正序的结果上看“快速排序”

会比“冒泡排序”更慢,这主要是“冒泡排序”中采用了提前结束排序的方法。有的书上这解释“快速排序”,在理论上

讲,如果每次能均匀划分序列,它将是最快的排序算法,因此称它作快速排序。虽然很难均匀划分序列,但就平均性能而

言,它仍是基于关键字比较的内部排序算法中速度最快者。

 

<5>希尔排序(Shell Sort):增量的选择将影响希尔排序的效率。但是无论怎样选择增量,最后一定要使增量为1,进行

一次直接插入排序。但它相对于直接插入排序,由于在子表中每进行一次比较,就可能移去整个经性表中的多个逆序,从

而改善了整个排序性能。希尔排序算是一种基于插入排序的算法,所以对数据有序敏感。

 

<6>归并排序(Merge Sort):归并排序是一种非就地排序,将需要与待排序序列一样多的辅助空间。在使用它对两个己有

序的序列归并,将有无比的优势。其时间复杂度无论是在最好情况下还是在最坏情况下均是O (nlog2n)。对数据的有序性

不敏感。若数据节点数据量大,那将不适合。但可改造成索引操作,效果将非常出色。


三、排序方法的选择

因为不同的排序方法适应不同的应用环境和要求,所以选择合适的排序方法很重要

(1)若n较小,可采用直接插入或直接选择排序。
当记录规模较小时,直接插入排序较好,它会比选择更少的比较次数;
但当记录规模较大时,因为直接选择移动的记录数少于直接插人,所以宜用选直接选择排序。
这两种都是稳定排序算法。


(2)若文件初始状态基本有序(指正序),则应选用直接插人、冒泡或随机的快速排序为宜(这里的随机是指基准取值的随机

,原因见上的快速排序分析);这里快速排序算法将不稳定。


(3)若n较大,则应采用时间复杂度为O(nlog2n)的排序方法:快速排序、堆排序或归并排序序。
快速排序是目前基于比较的内部排序中被认为是最好的方法,当待排序的关键字是随机分布时,快速排序的平均时间最短


堆排序虽不会出现快速排序可能出现的最坏情况。但它需要建堆的过程。这两种排序都是不稳定的。
 归并排序是稳定的排序算法,但它有一定数量的数据移动,所以我们可能过与插入排序组合,先获得一定长度的序列,

然后再合并,在效率上将有所提高。


(4)特殊的箱排序、基数排序
它们都是一种稳定的排序算法,但有一定的局限性:
1>关键字可分解。
2>记录的关键字位数较少,如果密集更好
3>如果是数字时,最好是无符号的,否则将增加相应的映射复杂度,可先将其正负分开排序。

 


四、AS中排列数组
1.申请一个长度为n的数组A:
var n:Number = 400;
var A:Array = new Array(n);
for (i=0; i<n; i++) {
A[i] = i;
}
trace(A);

 

2.将长度为n的数组打乱次序:
for (i=0; i<n; i++) {
var ran = int(Math.random()*n);
var temp = A[i];
A[i] = A[ran];
A[ran] = temp;
}
trace(A)

 

3.将数组中的所有元素倒排序:
A.reverse();
trace(A)


五、AS实现排序算法:
1.直接插入排序
var n:Number = 400;
var A:Array = new Array(n);
for (i=0; i<n; i++) {
A[i] = i;
}
for (i=0; i<n; i++) {
var ran = int(Math.random()*n);
var temp = A[i];
A[i] = A[ran];
A[ran] = temp;
}
trace(A);
trace("========== Order the array =========");
for (i=0; i<n; i++) {
var temp = A[i];
for (j=i; j>0 && temp<A[j-1]; j--) {
  A[j] = A[j-1];
  A[j-1] = temp;
}
}
trace(A);

 

2.直接选择排序

var n:Number = 400;
var A:Array = new Array(n);
for (i=0; i<n; i++) {
A[i] = i;
}
for (i=0; i<n; i++) {
var ran = int(Math.random()*n);
var temp = A[i];
A[i] = A[ran];
A[ran] = temp;
}
trace(A);
trace("========== Order the array =========");
var s:Number;
for (i=0; i<n-1; i++) {
s = i;
for (j=s+1; j<n; j++) {
  if (A[j]<A[s]) {
   s = j;
  }
}
var temp = A[i];
A[i] = A[s];
A[s] = temp;
}
trace(A);

 

3.冒泡排序
var n:Number = 400;
var A:Array = new Array(n);
for (i=0; i<n; i++) {
A[i] = i;
}
for (i=0; i<n; i++) {
var ran = int(Math.random()*n);
var temp = A[i];
A[i] = A[ran];
A[ran] = temp;
}
trace(A);
trace("========== Order the array =========");
for (i=0; i<n; i++) {
for (j=i; j<n; j++) {
  if (A[i]>A[j]) {
   var temp = A[i];
   A[i] = A[j];
   A[j] = temp;
  }
}
}
trace(A);

 

4.希尔排序
var n:Number = 400;
var A:Array = new Array(n);
for (i=0; i<n; i++) {
A[i] = i;
}
for (i=0; i<n; i++) {
var ran = int(Math.random()*n);
var temp = A[i];
A[i] = A[ran];
A[ran] = temp;
}
trace(A);
trace("========== Order the array =========");
var increment = 6;
while (increment>1) {
increment = int(increment/3+1);
Shellpass(increment);
}
function Shellpass(c) {
for (i=c; i<n; i++) {
  if (A[i]<A[i-c]) {
   var temp = A[i];
   j = i-c;
   do {
    A[j+c] = A[j];
    j = j-c;
   } while (j>0 && temp<A[j]);
   A[j+c] = temp;
  }
}
}
trace(A);

 

5.快速排序
var n:Number = 400;
var A:Array = new Array(n);
for (i=0; i<n; i++) {
A[i] = i;
}
for (i=0; i<n; i++) {
var ran = int(Math.random()*n);
var temp = A[i];
A[i] = A[ran];
A[ran] = temp;
}
trace(A);
trace("========== Order the array =========");
function QuickSort(A, low, hig) {
var i = low, j = hig;
var mid = A[int((low+hig)/2)];
do {
  while (A[i]<mid) {
   i++;
  }
  while (A[j]>mid) {
   j--;
  }
  if (i<=j) {
   var temp = A[i];
   A[i] = A[j];
   A[j] = temp;
   i++;
   j--;
  }
} while (i<=j);
if (low<j) {
  arguments.callee(A, low, j);
}
if (i<hig) {
  arguments.callee(A, i, hig);
}
}
QuickSort(A, 0, n-1);
trace(A);

 

6.二路归并
var n:Number = 400;
var A:Array = new Array(n);
for (i=0; i<n; i++) {
A[i] = i;
}
for (i=0; i<n; i++) {
var ran = int(Math.random()*n);
var temp = A[i];
A[i] = A[ran];
A[ran] = temp;
}
trace(A);
trace("========== Order the array =========");

var A1:Array = new Array(n);
for (k=1; k<n; k *= 2) {
MergePass(k);
}
function MergePass(len) {
for (i=0; i+2*len<n; i=i+2*len) {
  MergeA(i, i+len-1, i+2*len-1);
}
if (i+len<n) {
  MergeA(i, i+len-1, n-1);
}
}
function MergeA(low, m, hig) {
var i = low, j = m+1, z = 0;
while (i<=m && j<=hig) {
  A1[z++] = (A[i]<=A[j]) ? A[i++] : A[j++];
}
while (i<=m) {
  A1[z++] = A[i++];
}
while (j<=hig) {
  A1[z++] = A[j++];
}
for (z=0, i=low; i<=hig; z++, i++) {
  A[i] = A1[z];
}
}
trace(A);


教程到此结束
QQ:147461195(FL基理大师)


通过这个实例顺便介绍一下定义函数在程序中的应用,及代码的优化过程

思路:

1.用AS创建四个文本框第一个用于输入数字,第二个用于输入运算符,第三个还用于输入数字,最后一个用于输出结果。


2.设置一个按钮(count_btn),按下后跟据第二个文本框给出的运算符将第一个和第三个文本内容进行运算,并在最后一

个文本框内输出。


3.第一个文本框名为"in1"

第二个文本框名为"sign"

第三个文本框名为"in2"

第四个文本框名为"out"

可执行程序一:

var t_f:TextFormat = new TextFormat();

t_f.size = 20;

//设置文本格式中的字体为20

//================设置第一个文本框====================

_root.createTextField("in1", 1, 25, 50, 150, 25);

//创建一个文本框,注意再往下的文本框Y坐标是递增的
in1.setNewTextFormat(t_f);

//将设置好的文本格式赋给该文本框

in1.type =
"input";
//设置文本框类型为输入

in1.background = true;
//文本框有背景色

in1.backgroundColor =
0xffffff;
//背景色为白色

in1.border = true;
//文本框有边框

in1.borderColor = 0x0;
//边框颜色为黑色

in1.maxChars =
7;
//文本框中字符最大为7个

in1.restrict =
"0-9";
//文本框中允许输入的字符集为0到9

//============设置第二个文本框(基本同上)==============

_root.createTextField("sign", 2, 25, 80, 150, 25);
sign.setNewTextFormat(t_f);


sign.type = "input";

sign.background = true;

sign.backgroundColor = 0xffffff;

sign.border = true;

sign.borderColor = 0x0;

sign.maxChars = 1;

sign.restrict =
"+*///-";
//============设置第三个文本框(基本同上)==============


_root.createTextField("in2", 3, 25, 110, 150, 25);
in2.setNewTextFormat(t_f);


in2.type = "input";

in2.background = true;

in2.backgroundColor = 0xffffff;

in2.border = true;

in2.borderColor = 0x0;

in2.restrict = "0-9";

in2.maxChars =
7;
//==============设置第四个输出文本框===============


_root.createTextField("out", 4, 25, 165, 150, 25);
out.setNewTextFormat(t_f);


out.type = "dynamic";

out.background = true;

out.backgroundColor = 0xffffff;

out.border = true;

out.borderColor =
0x0;
//================按钮按下后进行计算================


count_btn.onRelease = function() {

if (sign.text == "+") {

  out.text =
int(in1.text)+int(in2.text);

}

if (sign.text == "-") {

  out.text =
int(in1.text)-int(in2.text);

}

if (sign.text == "*") {

  out.text =
int(in1.text)*int(in2.text);

}

if (sign.text == "/") {

  out.text =
int(in1.text)/int(in2.text);

}

};

在这个程序中的们看到对于文本框属性的设置重复了多次,为了精简代码我们考虑使用函数来解决代码的重用问题,请看

第二段程序

可执行程序二:

var t_f:TextFormat = new TextFormat();

t_f.size = 20;
function F(txt) {

txt.setNewTextFormat(t_f);

txt.background = true;

txt.backgroundColor = 0xffffff;

txt.border = true;

txt.borderColor = 0x0;

txt.type = "input";

if (txt == sign) {

  txt.maxChars = 1;

  txt.restrict = "+*///-";

}

if (txt == out) {

  txt.type = "dynamic";

}

if (txt == in1 || txt == in2) {

  txt.maxChars = 7;

  txt.restrict = "0-9";

}

}
_root.createTextField("in1", 1, 25, 50, 150,
25);

F(in1);

_root.createTextField("sign", 2, 25, 80, 150, 25);

F(sign);

_root.createTextField("in2", 3, 25, 110, 150,
25);
F(in2);
_root.createTextField("out",
4, 25, 165, 150, 25);

F(out);

count_btn.onRelease = function() {

if (sign.text == "+") {

  out.text =
int(in1.text)+int(in2.text);

}

if (sign.text == "-") {

  out.text =
int(in1.text)-int(in2.text);

}

if (sign.text == "*") {

  out.text =
int(in1.text)*int(in2.text);

}

if (sign.text == "/") {

  out.text =
int(in1.text)/int(in2.text);

}

};
//在这段程序中我们通过调用函数来设置属性,属性相同的地方写在函数的最开始,不同的地方用if语句进行判断后再赋

最后我们再优化一下代码:使用with语句,批量设置属性,再将按钮中的if改为switch使他的结构更加清晰,可读性更好


可执行程序三:

var t_f:TextFormat = new TextFormat();

t_f.size = 20;
function F(txt) {

with
(txt) {

  setNewTextFormat(t_f);

  background = true;

  backgroundColor =
0xffffff;

  border = true;

  borderColor = 0x0;

}

if (txt == sign)
{
  with
(txt)
{
   type
= "input";

   maxChars =
1;

   restrict =
"+*///-";

  }
}

if (txt == out)
{
  txt.type
= "dynamic";
}

if (txt == in1 || txt == in2) {

  with
(txt) {

   type =
"input";

   maxChars =
7;

   restrict =
"0-9";

  }


}

}

_root.createTextField("in1", 1, 25, 50, 150, 25);

F(in1);

_root.createTextField("sign", 2, 25, 80, 150, 25);

F(sign);

_root.createTextField("in2", 3, 25, 110, 150, 25);

F(in2);

_root.createTextField("out", 4, 25, 165, 150, 25);

F(out);

count_btn.onRelease = function()
{
switch (sign.text)
{

case "+" :

  out.text =
int(in1.text)+int(in2.text);

  break;

case "-" :

  out.text =
int(in1.text)-int(in2.text);

  break;

case "*" :

  out.text =
int(in1.text)*int(in2.text);

  break;

case "/" :

  out.text =
int(in1.text)/int(in2.text);

  break;

}

};
//好了到这里就完成了代码的由繁到简的优化,希望同学们在今后的实践中加深领悟。


FLASH充电1: TextField
常用属性及事件处理函数
常用属性:

1.createTextField("实例名", 深度, x坐标, y坐标, 宽度,
高度)

用来创建一个文本框。

例:createTextField("txt", 1, 10, 20, 100, 100);

2.autoSize:控制文本字段的自动大小调整和对齐。


autoSize 的可接受值为 "none"(默认值)、"left"、"right" 和
"center"。当您设置 autoSize 属性时,true 是 "left" 的同义词,false
是 "none" 的同义词。

注意:当txt.autoSize = true 时,表示自动匹配尺寸

这时createTextField("txt", 1, 10, 20, 0, 0)宽和高可以为0

3.background:指定文本字段是否具有背景填充;


backgroundColor:文本字段背景的颜色。

注意:这两句要配合使用:

例如:txt.background = true;

   
txt.backgroundColor = 0xff0000;

4.border:指定文本字段是否具有边框。

borderColor:文本字段边框的颜色。

注意:这两句一般要配合使用:

例如:txt.border = true;

   
txt.borderColor = 0x0;

5.selectable:一个布尔值,指示文本字段是否可选。


例如:txt.selectable=false 表示txt文本字段可选。

6.textColor:指示文本字段中文本的颜色。


例如:txt.textColor = 0xFF0000;

7.type:指定文本字段的类型。


有两种值:

"dynamic":指定不能由用户对其进行编辑的动态文本字段;

"input":指定输入文本字段。

例如: txt.type = "dynamic" 指定txt的类型为动态文本;

    
txt.type = "input" 指定txt的类型为输入文本。

8.wordWrap:一个布尔值,指示文本字段是否自动换行。


例如:txt.wordWrap = true 表示自动换行。

9.multiline:指示文本字段是否为多行文本字段。


例如:txt.multiline = true 表示txt文本框为多行。

10.hscroll:指示当前水平滚动位置。

注意:在txt为单行不换行的情况下

一般在按钮中写入:txt.hscroll+=5。

scroll:文指示当前垂直滚动位置(与hscroll相对)。

注意:在txt为多行且换行的情况下

一般在按钮中写入:txt.scroll+=5。

11.maxChars:指示文本字段最多可容纳的字符数。


例如:txt.maxChars = 7 表示txt最多容纳7个字符。

12.password:指定文本字段是否是密码文本字段。


例如:txt.password = true 表示txt中的字段以密码形式出现。

13.restrict:约束用户可输入到文本字段中的字符集。


例如:

<1>仅允许在文本字段中输入大写字符、空格和数字:

txt.restrict = "A-Z 0-9";
<2>包含除小写字母之外的所有字符:

txt.restrict = "^a-z";
<3>可以使用反斜杠输入 ^ 或 -
的本义。认可的反斜杠序列为 /-、/^ 或
//。反斜杠在字符串中必须是一个本义字符,因此在
AS中指定时必须使用两个反斜杠。下面的代码只包含 - 和 ^ :

txt.restrict = "//-//^";
<4>可在字符串中的任何地方使用
^,以在包含字符与排除字符之间进行切换。包含除大写字母 Q
之外的大写字母:

txt.restrict = "A-Z^Q";

常用事件处理函数:

1.TextField.onChanged = function(){}

在文本字段的内容发生更改时调用函数。

例如:只要文本框内的段发生变化就输出文本内容

_root.createTextField("txt", 99, 10, 10, 300, 20);

txt.border = true;

txt.type = "input";

txt.onChanged = function() {

trace(txt.text);

};

2.TextField.onKillFocus = function()
{}

在文本字段失去键盘焦点时调用函数。

例如:在文本框失去焦点时,输出文本内容

_root.createTextField("txt", 99, 10, 10, 300, 20);

txt.border = true;

txt.type = "input";

txt.onKillFocus = function() {

trace(txt.text);

};

3.TextField.onSetFocus = function()
{}

在文本字段接收键盘焦点时调用函数。

例如:在文本框接收到焦点时,清空文本内容

_root.createTextField("txt", 99, 10, 10, 300, 20);

txt.border = true;

txt.type = "input";

txt.onSetFocus = function() {

txt.text = "";

};

重要方法:

setNewTextFormat:设置文本字段的默认新文本格式。

例如:

var t_f:TextFormat = new TextFormat();

t_f.bold = true;

t_f.font = "Arial";

this.createTextField("txt", 1, 40, 10, 70, 20);

txt.border = true;

txt.setNewTextFormat(t_f);

txt.text = "Hello World!";


FLASH充电2: TextFormat 常用属性简介

1.var t_f:TextFormat = new TextFormat();

申请一个TextFormat对象并实例化。

2.TextFormat.align:段落的对齐方式

"left"--左对齐。

"center"--居中。

"right"--右对齐。

"justify"--两端对齐。

例: t_f.align = "center"

3.TextFormat.bold:指示文本是否为粗体字。

例: t_f.bold = true

4.TextFormat.color:指示文本的颜色。

例: t_f.color = 0xff0000


5.TextFormat.font:文本的字体名称,以字符串形式表示。
例:
t_f.font = "黑体"


6.TextFormat.italic:指示使用此文本格式的文本是否为斜体。

例: t_f.font = true


7.TextFormat.underline:指示使用此文本格式的文本是否有下划线。


例: t_f.underline = true


8.TextFormat.leftMargin:段落的左边距,以磅为单位。


例: t_f.leftMargin = 5


9.TextFormat.rightMargin:段落的右边距,以磅为单位。
例:
t_f.rightMargin = 5


10.TextFormat.size:使用此文本格式的文本的磅值。


例: t_f.size = 20


11.TextFormat.indent:指示从左边距到段落中第一个字符的缩进的整数。

例: t_f.indent = 5

12.TextFormat.url:指示使用此文本格式的文本链接所至的
URL。

例: t_f.url = "http://blog.sina.com.cn/yyy98"

教程到此结束
QQ:147461195(FL基理大师)


第一次在fanflash上看到这个实例,感觉很不可思议

仔细研究一下发现,作者的构思还是很巧妙的,今天拿来与大家分享一下

这个实例可以说结合了BitmapData类的技术与Tween类的动感。

思路:
1.用AS创建一个空文本框,存储欲显示的字;
2.把这个文本框看成一个位图,并存储其位图数据;
3.逐行扫描这个位图数据,把有文字信息的像素点都存储到数组中;
4.最后根据数组复制出"点",并使每个"点"移动到相应的位置。
步骤1:

  
绘制10*10的圆点,保存为影片剪辑,连接—>导出—>标志符"dot"
步骤2:
加入AS代码:
import
flash.display.BitmapData;

import mx.transitions.Tween;

import mx.transitions.easing.*;

//导入BitmapData及Tween类

_root.createTextField("txt", -1, -100, -100, 0, 0);

txt.autoSize = true;

txt.text = "输入要显示的文字";

//创建一个空的文本框,存储输入的文本

var bm:BitmapData =
new BitmapData(txt._width,txt._height, false,
0xffffff);

bm.draw(txt);

//把txt看成位图,并把txt位图信息存入mb

var DotArray:Array
= new Array();

//申请一个数组用于存储mb位图信息

var w:Number = 4;

var h:Number = 4;

//w,h分别为点间宽度和高度
for (y=0; y<txt._height;
y++) {

for (x=0; x<txt._width; x++) {

  if (bm.getPixel(x, y) != 0xffffff) {

   DotArray.push({x:x*w,
y:y*h});
   //逐行逐列取像素,把有字的像素位置存入数组并乘上w,h以扩展距离

  }


}

}

_root.createEmptyMovieClip("MC",
-1);

MC._x = 10;

MC._y = 150;

//============根据数组复制"点"===============


for (var i = 0; i<DotArray.length; i++) {

var p = MC.attachMovie("dot", "dot"+i,
i);
p.cacheAsBitmap =
true;
//将"点"进行位图缓存

p._x =
Math.random()*Stage.width;

p._y =
Math.random()*Stage.height;
//给每个"点"一个随机的起点

p.tox
= DotArray[i].x;

p.toy =
DotArray[i].y;
//tox,toy是每个点要移动到的终点
var speed =
Math.random()*4
new Tween(p, "_x",
Back.easeOut, p._x, p.tox, speed, true);

new Tween(p, "_y", Back.easeOut, p._y, p.toy, speed,
true);
//利用Tween类,让每个"点"移动到他们的终点坐标


}

Flash充电:MovieClip.cacheAsBitmap
属性
1.作用:如果设置为 true,则 Flash Player
将缓存影片剪辑的内部位图表示。这可以提高包含复杂矢量内容的影片剪辑的性能。

2.原理:矢量图体积小,但比较消耗计算资源;位图则比较消耗内存资源,但对计算资源消耗小。

3.简单地说:cacheAsBitmap就是把矢量图转化成位图;节省CPU,但消耗内存,可以提高对于矢量图的运算速度。

4.注意:cacheAsBitmap最适用于包含大量静态内容,并不需要频繁scale和旋转的MC里。

5.默认:当你添加filter(滤镜)到MC上,cacheAsBitmap自动设置为true,这点即使你强行让cacheAsBitmap=false也改变

不了。只有当你去掉filter,cacheAsBitmap将返回最新被设置的逻辑值。

 

教程到此结束
QQ:147461195(FL基理大师)


一、计算机中显示的图形一般可以分为两大类——矢量图和位图。


矢量图(vector):使用直线和曲线来描述图形,这些图形的元素是一些点、线、矩形、多边形、圆和弧线等等,它们都是

通过数学公式计算获得的。众所周知Flash就是一款矢量动画制作软件。在AS中使用的填色(beginFill),画线(lineTo)等

命令都是基于对矢量图的操作。


位图(Bitmap):一般是用于照片品质的图像处理,是由许多像小方块一样的像素组成的图形。简单地说,位图就是以无数

的色彩点组成的图案。位图(Bitmap)也就是我们今天要介绍的。


二者比较:

1.矢量图可以无限放大,而且不会失真; 而位图会失真。

2.位图由像素组成而矢量图由矢量线组成。

3.位图可以表现的色彩比较多;而矢量图则相对较少。

4.矢量图体积小,但比较消耗计算资源;位图则比较消耗内存资源,但对计算资源消耗小。

二、BitmapData类的概念

BitmapData类可用于在文档中创建可任意调整大小的透明或不透明位图图像,并且可以在运行时以各种方式对它们进行处

理。可以把
BitmapData对象看成一个特殊的数组,专门用来存储位图的像素点阵信息。如果一个位图大小是100*100,那么

BitmapData中就好比一
个存储在一个100*100的二维数组,对应存储这10000像素的颜色值。

三、BitmapData类的使用

import flash.display.BitmapData;

//导入BitmapData类

var bm = new
BitmapData(width,height,transparent,fillcolor);

//实例化

四、BitmapData构造函数

public BitmapData(width, height, [transparent], [fillColor])

width(宽):位图数据的宽度(像素);

height(高): 位图数据的高度(像素);

[transparent(透明度)]:
是否支持每个像素具有不同的透明度;

[fillcolor(添充色)]:
用于填充位图图像区域。默认为0xFFFFFFFF(白色)

*[中括号]表示可选参数

例如(创建一个100*100的位图数据):

import flash.display.BitmapData;

var bm:BitmapData = new
BitmapData(100,100,false,0xffff00)

五、BitmapData.draw()方法

Draw()方法简单地理解为:复制像素到BitmapData对象中。

例如:在主场景有一个影片剪辑,实例名为"pic"

import flash.display.BitmapData;

var bm:BitmapData = new BitmapData(100, 100);

bm.draw(pic);
//bm复制pic的像素

_root.createEmptyMovieClip("mc", 10);

mc._x = mc._y=150;

mc.attachBitmap(bm,
1);
//用mc加载位图数据bm,深度为1。

*注意:位图在影片剪辑(pic)中的位置:

 

在使用draw()方法复制像素时,永远是从mc的(0,0)点开始取。
所以小于(0,0)位置的像素都不会被取到

 

应正确放置位图在影片剪辑中的位置(注册点在左上(0,0))

六、Rectangle

所以介绍Rectangle
类是因为它常与BitmapData类配合使用。

1.作用:在BitmapData类中用于定义位图图像大小和位置的矩形。


2.Rectangle 类的使用
import
flash.geom.Rectangle;

public Rectangle(x, y, width, height)

x - 矩形左上角的 x 坐标。

y - 矩形左上角的 y 坐标。

width - 矩形的宽度,以像素为单位。

height - 矩形的高度,以像素为单位。


例如(一个100*100的矩形):

import flash.geom.Rectangle;

myRect = new Rectangle(0,0,100,100);

好啦,说了这么多理论知识,都是为我们的实例做铺垫的,下面就开始动手操作吧。


实例1:放大镜效果[BitmapData.
copyPixels()]


思路:1.点击图片后,从点击处复制一块(100*80)像素;


   
2.把复制出来的像素(bm2)加载入mc中,并放大mc。
步骤一:


在主场景中放入一位图,保存为影片剪辑,实例名为"pic",放入舞台中;

 

注意:该位图在pic中的注册点应为左上(0,0),以确保正确显示。

步骤二:
加入AS代码:

import
flash.display.BitmapData;

import flash.geom.Rectangle;

var bm1:BitmapData = new BitmapData(pic._width, pic._height);

bm1.draw(pic);
//创建一个与图片大小相同的位图数据类,并把pic所有像素复制进去


pic.onMouseDown =
function() {

var bm2:BitmapData = new BitmapData(100, 80, true, 0);

bm2.copyPixels(bm1, new Rectangle(_xmouse,
_ymouse, 100, 80), new Point(0,
0));
//从bm1中复制一块像素到bm2,像素起点是鼠标点击的处,大小为100*80


_root.createEmptyMovieClip("mc", 10);

mc.attachBitmap(bm2,
1);
//显示bm2中的位图

mc._x = _xmouse;

mc._y = _ymouse;

mc._xscale =
mc._yscale=150;
//放大mc

};
_root.onMouseUp = function()
{

mc.removeMovieClip();

};


实例2:卷动图效果[BitmapData.
copyPixels()]


思路:1.把图片纵向切为num条,并为每条取像素;

   
2.创建num个影片剪辑,分别存放每条像素;

   
3.设置每个影片剪辑的X坐标;Y坐标一块比一块高;

   
4.结合Tween类使每个条都从天上落下。
步骤一:

 

在主场景中放入一位图,保存为影片剪辑,实例名为"pic",放入舞台中;

 

注意:该位图在pic中的注册点应为左上(0,0),以确保正确显示。

步骤二:

加入AS代码:

import
flash.display.BitmapData;

import flash.geom.Rectangle;

import mx.transitions.Tween;

import mx.transitions.easing.*;

var num = 80;
//把图分成80份
var pW =
pic._width/num;
//确定每份的宽度为
var
pH =
pic._height;
//因为切成竖条形所以高度不变
var
bm1:BitmapData = new BitmapData(pic._width, pic._height);

bm1.draw(pic);

pic._visible = false;
for (i=0; i

var bm2:BitmapData = new BitmapData(pW,
pH);

bm2.copyPixels(bm1, new
Rectangle(i*pW, 0, pW, pH), new Point(0,
0));
//用i变量*每块宽度,确定取像素的位置

var
p:MovieClip = _root.createEmptyMovieClip("mc"+i, i);

p.attachBitmap(bm2,
this.getNextHighestDepth());

p._x =
i*pW;
//排好X坐标
p._y
=
-i*pH/5;
//把Y坐标置到舞台上面去,一块比一块高

new Tween(p,
"_y", Bounce.easeOut, p._y, 0, (i/10+1),
true);
//------------------试替换代码看看效果-------------------


//new Tween(p, "_y", Back.easeInOut, p._y, 0,
(i/10+1), true);

//new Tween(p, "_y", Strong.easeIn, p._y, 0,
(i/10+1), true);

//new Tween(p, "_y", Elastic.easeOut, p._y, 0,
(i/10+1), true)

}


实例3:位图填充[BitmapData.
beginBitmapFill()]


思路:
1.用loadBitmap("id")加载位图,注意:这是个静态方法;
    
2.创建一个MC,绘出一个与舞台同样大小的矩形,并进行填充.


步骤一:
   

  
任意导入一张位图,在库中右击该位图->链接->标识符为"pic"

步骤二:

加入AS代码:

import
flash.display.BitmapData;

var bm:BitmapData = BitmapData.loadBitmap("pic");
//根据屏幕的大小来绘制绘画区域,用以beginBitmapFill来添充

_root.createEmptyMovieClip("MC",
10);

with (MC) {

beginBitmapFill(bm);
moveTo(0,
0);

lineTo(Stage.width, 0);

lineTo(Stage.width, Stage.height);

lineTo(0, Stage.height);

lineTo(0, 0);

endFill();

}


实例4:位图切片[BitmapData.
beginBitmapFill()]


思路:
1.点击到原图上,进行画圈,并在圈中填充位图;

      2.点击在切片上,进行拖动。


步骤一:


在主场景中放入一位图,保存为影片剪辑,实例名为”pic”,放入舞台中;

 

注意:该位图在pic中的注册点应为左上(0,0),以确保正确显示。

步骤二:
加入AS代码:

import
flash.display.BitmapData;

var bm:BitmapData = new BitmapData(pic._width, pic._height);

bm.draw(pic);

var draw:Boolean = false;
pic.onPress = function() {

if (mc.hitTest(_xmouse, _ymouse, true)) {

  mc.startDrag();
  //如果鼠标在mc上,开始拖动它

} else {

  draw = true;

  mc =
_root.createEmptyMovieClip("mc", 1);
  mc.lineStyle(2,
0xFF0000);

  mc.beginBitmapFill(bm);

  mc.moveTo(_xmouse-this._x,
_ymouse-this._y);
  //移动起点到此

}

};
pic.onMouseMove = function() {

if (draw) {

  mc.lineTo(_xmouse-this._x,
_ymouse-this._y);
  //如果draw状态为真,移动鼠标就draw 

}

};
pic.onMouseUp = function() {

if (draw) {

  draw = false;

  mc.endFill();
  //填充结束

} else {

  mc.stopDrag();

}

};

关于BitmapData类的应用还有很多很多,一句两句还说不完,今后再做介绍。
最后共享一些网络上的相关资料:
Flash8.net(闪吧):

flash 8 BitmapData类的应用

Flash8平铺网页背景

webstudio(万博思图):

Flash8 BitmapData


教程到此结束
QQ:147461195(FL基理大师)


Tween类,在推出FlashMX时就出现了,允许您轻松地在舞台上移动、缩放和淡入淡出影片剪辑。实质是用于添加AS过渡动

画,使用非常的方便。

Tween类的使用:

Tween类算是一个外部类,所以使用前应先导入:

import
mx.transitions.Tween;

Tween类中easing方法的导入:用easing.*打开整个包,所有方法也都被载入了

import
mx.transitions.easing.*;

Tween类构造函数中各参数介绍

function Tween(obj, prop, func, begin, finish, duration,
useSeconds)
{

    //
代码……

}

obj(实例名) Tween 实例的目标影片剪辑对象。

prop(属性) obj的属性的字符串名称。

func(效果) 缓动效果的缓动方法。

begin(开始)  属性的开始值。

finish(结束)
属性的结束值。

duration(时间)
一个数字,指示补间动画的时间长度。

useSeconds(使用秒) 一个布尔值,如果该值为
true,则指示使用秒,如果为 false,则使用帧。
例如:
new Tween(mc, "_x",
Back.easeInOut, mc._x, 300, 4, true);

缓动效果(func参数):

Back
过渡范围外扩展动画一次,以产生从其范围外回拉的效果。

Bounce
过渡范围的弹跳效果。弹跳数与持续时间相关,持续时间越长,弹跳数越多。


Elastic
超出过渡范围的弹性效果。弹性量不受持续时间影响。

Regular
较慢的运动。加速效果、减速效果或这两种效果。

Strong 较慢的运动。此效果类似于 Regular
缓动类,但它更明显。

None
无任何减速或加速效果的运动。此过渡也称为线性过渡。

这六种缓动计算类的每一种都有三个缓动方法,下表中描述了这些缓动方法:


easeIn 在过渡的开始提供缓动效果。

easeOut 在过渡的结尾提供缓动效果。

easeInOut 在过渡的开始和结尾提供缓动效果。

easeNone 指明不使用缓动计算。只在 None
缓动类中提供。

看到这儿,是不是有点儿晕,呵呵,理论就是这样。Tween类的本质实际上就是把对象的属性从Begin(开始)变化到

Finish(结束),并加以特效。没关系,下面做个实例,让理论实践相结合,注意对照上面的参数


实例1:控制小球


思路:点击鼠标后,小球向所点击位置移动并带有缓动效果;


步骤1:

  
绘制一个小球,保存为影片剪辑,放到舞台中,实例名为"ball"

步骤2:

加入AS代码(注释部分:请大家进行替换试试效果):

import
mx.transitions.Tween;

import mx.transitions.easing.*;
//导入Tween类及方法
_root.onMouseDown
= function() {

new Tween(ball, "_x",
Back.easeInOut, ball._x, _xmouse, 3, true);

new Tween(ball, "_y", Bounce.easeInOut, ball._y,
_ymouse, 3, true);

//------------------------------------------------------------------


//new Tween(ball, "_x", Strong.easeInOut,
ball._x, _xmouse, 3, true);

//new Tween(ball, "_y", Elastic.easeInOut,
ball._y, _ymouse, 3, true);

//------------------------------------------------------------------


//new Tween(ball, "_x", Elastic.easeInOut,
ball._x, _xmouse, 3, true);

//new Tween(ball, "_y", Elastic.easeInOut,
ball._y, _ymouse, 3, true);

//效果还有很多,朋友们发挥主观能动性自行开发...
...

};

//通过这个实例我们发现,即使_x和_y给予不同的缓动效果小球都可以准确地到达指定位置,只是过程不同而已。


实例2:飞入菜单


思路:1.初始化时把mc放到舞台外,这样才能出现飞入效果;


   
2.初始化时把mc的_yscale缩小,为放大效果做准备。


步骤1:
  
随便画些什么,保存为影片剪辑,放在舞台中心,实例名为"mc";

  
再绘制两个按钮在舞台中,实例名分别为"in_btn","out_btn";

步骤2:
加入AS代码(注释的new
Tween()部分请大家可替换后试试效果):

import
mx.transitions.Tween;

import mx.transitions.easing.*;

//导入Tween类及其方法

mc._x = 1000;

mc._yscale = 10;
//设置mc的初始位置和高度

in_btn.onRelease = function() {

//飞入效果

new Tween(mc, "_yscale",
Bounce.easeOut, mc._yscale, 100, 4, true);

//mc._yscale放大到100

new Tween(mc, "_x",
Back.easeOut, mc._x, Stage.width/2, 5, true);

//mc._x移动到舞台宽度的一半(即舞台中心)

//new Tween(mc, "_x", Bounce.easeOut, mc._x,
Stage.width/2, 5, true);

//new Tween(mc, "_x", Elastic.easeOut, mc._x,
Stage.width/2, 5, true);

//new Tween(mc, "_x", Regular.easeOut, mc._x,
Stage.width/2, 5, true);

//new Tween(mc, "_x", Strong.easeOut, mc._x,
Stage.width/2, 5, true);

//new Tween(mc, "_x", None.easeNone, mc._x,
Stage.width/2, 5, true);

};


out_btn.onRelease = function() {

//飞出效果

new Tween(mc, "_yscale",
Bounce.easeIn, mc._yscale, 50, 3, true);

//mc._yscale缩小到50

new Tween(mc, "_x",
Elastic.easeIn, mc._x, -1000, 5, true);

//mc._x移动到-1000(即舞台外部)

//new Tween(mc, "_x", Bounce.easeOut, mc._x,
-1000, 5, true);

//new Tween(mc, "_x", Elastic.easeOut, mc._x,
-1000, 5, true);

//new Tween(mc, "_x", Regular.easeOut, mc._x,
-1000, 5, true);

//new Tween(mc, "_x", Strong.easeOut, mc._x,
-1000, 5, true);

//new Tween(mc, "_x", None.easeNone, mc._x,
-1000, 5, true);

};


Flash充电1:new Tween()参数解析

 

Flash充电2:六类缓动效果的easeOut方法演示

 

教程到此结束
QQ:147461195(FL基理大师)


“如果看看微软的网站就会发现,它使用大量的Flash……”Adobe首席执行官 Bruce Chizen与微软再次针锋相对。在电

子文档领域,
Adobe与微软在几年前就开始交手,随着9月微软即将正式发布Silverlight,双方将在互联网富媒体领域展开新一轮竞争

  Silverlight到底是什么?它其实是一个跨浏览器、跨平台的插件,为网络带来下一代基于.NET的媒体体验和丰富的

交互式应用程序。它也是一
种新的Web呈现技术,无论是在浏览器内、在多个设备上还是在桌面操作系统(如Apple Macintosh)中,用户都可以获得内

容丰富、视觉效果绚
丽的交互式体验。因此,Silverlight尽管还未正式亮相,但已经被称为Flash杀手。要知道两年前Adobe以34亿美元收购
Macromedia时,也正是冲着Flash来的。现在,Flash带来的收入已经超过Adobe总收入的1/2。这意味着Silverlight的发
布使微软剑指Adobe的核心利润来源,双方竞争也随即升级。


  短兵相接

  从整个互联网发展趋势来看,表现形式已经从单一的文本形式,发展到3D图片、动画、音频、视频。“现在可以说是

Hi-Fi的Web世界。”在近日举行
的Microsoft Silverlight预览会上,微软中国有限公司平台与开发合作部总监林毅已经开始这样定义互联网世界。可以


Silverlight成为微软互联网战略的重要组成部分,而Flash则代表Adobe在设计、制图等传统领域之外的重要新兴市场。

  此外,互联网技术层面的发展趋势是控制性,简单说,就是在业务上表现为交互性,这样发展的必然就是网站的个性

化和技术的丰富性。当然,Adobe清醒
地认识到这点:Flash在今天所要做出的转变,是从网络动画领域转变到应用程序领域。Adobe眼中的视频不再仅仅是

Flash两年前所看重的编辑,而
是指整个工作流,包括实时编辑、后期制作、流媒体、DRM数字保护、发布等等。而微软的Silverlight从诞生之时起就不

仅仅是客户端插件,它提供
灵活的编程模型,可以很方便地集成到现有的网络应用程序中。它有一整套开发工具。去年微软刚刚推出的针对设计者的
Microsoft Expression 套件,就可以通过XAML语言与微软针对程序开发者的Visual Studio结合起来,从而提高网站应用
的效率。

  赛迪顾问软件产业研究中心总经理牟淑惠表示,整合是微软的最大竞争优势,expression套件提供了从构建网页、动

画设计、多媒体资产管理等等一
整套解决方案。这套解决方案为那些在竞争中寻找突破点的网站以及艺术设计类公司提供了一套很好的工具,可以更容易

锁住用户,锁住用户也就锁住了市场竞争
力。双方的设计工具套件惊人地相似:如Expression套件中的Web Designer、Image Designer对应Adobe的
Dreamweaver、Illustrator,而Expression Blend则是用于创建连接Web的Windows用户体验的专业工具,体现
混合协同开发,从名称上即表现出交互设计功能。除了功能强大的无代码交互外,从前端的界面元素,也可以直接关联到

后端的编程语言和代码,处理更为复杂的交
互。


  竞争门槛

  当然,早起一步的Flash不仅在全球拥有超过7亿的客户端用户,它更为专注于IT专业人士、创作人士、网络设计者或

图片设计者等专业人士。但
Adobe也不会墨守陈规。已经发生变化的一个情况是:它对低端市场逐渐重视。看看全球最大的视频分享网站YouTube,它

让人人都想成为视频发行商,
人人都想成为创作型人才。因此Adobe也推出了PhotoBucket和Remix等产品,并在考虑免费软件的商业模式。现在,重要

的视频分享网站
YouTube、Myspace都选用Flash Video Player来播放自己的视频。此外,尽管.NET、Visual Studio、
MSDN是微软在程序开发者中占据主要市场的三大因素,但是设计者普遍使用的是Mac平台,这就让微软Expression套件的

推广遇到难题。


  但是,即将正式上市的Silverlight也拥有自己更胜一筹的技术特性,让它更符合目前Hi-FiWeb世界的需求和更高的

商业价值。在预览会上,微软给人印象最深的包括三个特性:流畅高清视频效果、对搜索优化的支持,以及商业解决方案


  高清晰视频

  由于体积上的压缩和编码上的简单化,省略较多的画面细节,目前市场上广泛使用的视频格式的视频效果并不理想,

难以满足较长时间观看的要求。而
Silverlight支持720HD(High Definition),这是由电影电视工程师协会所提出的视频压缩标准,其技术基础来自微软的
Windows Media Video(WMV-9)。因此,Silverlight具有高清视频质量,通过Windows Media技术,传输流量
可降低46%,并且和现有的Windows Media流量配置方案兼容。如果采用下一代Windows Server系统中的IIS媒体包,流量

还将进
一步下降。VC-1编码的高清晰视频,也可以在当前网络条件下进行传输。

  此外,在播放效果上Silverlight非常流畅。它播出视频及动画的效果很好,不会因为传输或播放大量内容而影响播

放质量—这一问题是现有技术普
遍遇到的障碍,同时也对消费者体验造成巨大影响。而且,Silverlight读取数据及更新外观的时候,不会通过刷新整体

页面来打断用户操作。

  而且Silverlight浏览器插件的安装程序简单,目前预览版的体积约为1.36MB。当用户遇到使用Silverlight开发的网

页时,可以
迅速安装这一插件。Silverlight内建的视频及动画广告解决方案灵活性很高,当传输广播类型的视频或是动画广告时,

不会影响视频的质量,而这一问
题是现有技术普遍遇到的问题。


  解决搜索难题

  Flash未能突破的关键技术之一就是对视频搜索引擎的支持。除了眩目的设计和动态的交互,Flash主要针对目前网站

的商业目的,尤其是视频网站。
因为,网页浏览量(Page View)对于网站的发展非常重要,而很大一部分浏览量来源于搜索结果。但目前大部分视频分享

网站所使用的技术基本上都不支
持SEO(搜索引擎友好),从而造成视频的搜索收录率偏低。这也是很多运营视频分享平台最为关心的地方。虽然有些网站

采用元数据的方式来提高收录数量,但
效果并不理想。

  而微软Silverlight中的页面描述采用XAML文件格式,而且并不编译成二进制文件,它天生支持SEO。另外,

Silverlight中的各
种资源文件均是作为单独文件方式存在,而不是作为二进制文件的内嵌式资源文件存在。这可以说是一个非常重要的技术

商业特性。也就是说
Silverlight不仅在视频设计表现形式上毫不逊色,而且很多用户可能会因为这一重要的技术背后潜在的重要商业价值而

成为Silverlight第
一批用户。


  技术商业价值

  Silverlight的另一个技术商业价值是它低成本的解决方案。微软Silverlight设计工具Expression和
Visual studio结合起来,各大公司中超过一半的编程人员使用的是微软的技术,而Expression的学习成本比较低,两者

的结合可以打破当
前普遍存在的一个问题:设计及开发基于不同的平台,导致技术壁垒及开发成本过高。作为目前国内最大的BBS技术供应

商,全球已有超过50万家独立网站采用
了Discuz!的技术与产品。Discuz!NT产品经理王炳坤试用Silverlight后认为,对于开发人员来说,Silverlight可以充


利用他们既有的.NET开发技术,从而大大降低学习与培训成本。而且,业界目前普遍使用的解决方案,其工具以及服务器

价格都非常高昂,尤其是服务器。而
Silverlight的后台对服务器类型没有要求。因此,微软测算,如果以不限流量的解决方案价格对比,其价格仅是主流解

决方案价格的十分之一。

  此外,越来越多的互联网内容提供商开始构建自己的在线休闲游戏平台。但由于国内恶意软件的现状,很多用户不敢

下载相关的ActiveX控件,大大降低
了在线休闲游戏的普及率。而Silverlight的独特性质则可以避免此问题。同时,其先天对于游戏特性的支持,也使它成

为在线休闲游戏平台的第一选
择。另一例子是,目前,业界常见的Windows边栏小工具大部分使用HTML形式呈现,内容表现单一。而Silverlight则可以

提供更加丰富的表
现形式,有助于提升用户忠诚度,并扩展赢利模式。

 

看到这个动画,不禁让人想到南迁的大雁,一会儿排成"人"字形,一会儿排成"一"字形的壮观场面

思路:1.createEmptyMovieClip(MC),位于舞台中央,使之不断旋转;


2.用MC作载体,复制出num(150)个(p0~p149)影片,全部都依附于MC上;

3.AS中共有2个函数(function),分别为Change()和getShape():
Change():首先,获得一个随机图形编号(shape),然后为所有MC["p"+i]点设置大小及透明度,再调用getShape()获得该点的

目标坐标;


getShape():根据shape编号,返回组成该图形的目标坐标;

4.用数组PS[0]存X坐标,PS[1]存Y坐标;

5.MC["p"+i].onEnterFrame:"跑"向各自的目标点.

步骤1:

  
绘制10*10的圆点,保存为影片剪辑,连接—>导出—>标志符"p"

步骤2:

加入AS代码:

_root.createEmptyMovieClip("MC",
10);

MC._x = 200;

MC._y = 150;

MC.onEnterFrame = function() {

this._rotation += 2;

};

var num:Number = 150;
//圆点p的个数

for (i=0; i<num; i++) {

MC.attachMovie("p", "p"+i, i);

}

var PS:Array = new
Array(2);
//PS[0]存储X坐标,PS[1]存储Y坐标.

_root.onMouseDown = function()
{

Change();
//鼠标点击后变换图形


};

function
Change() {

var shape =
int(Math.random()*2);
//获得随机图形

for (i=0; i<num; i++) {

  p =
MC["p"+i];
  p._xscale
= p._yscale=50+Math.random()*50;

  p._alpha =
50+Math.random()*50;

  getShape(shape);

  p.tox = PS[0];

  p.toy =
PS[1];
//调用getShape()函数后,获得MC["p"+i]的X,Y目标坐标

  p.onEnterFrame =
function() {
   this._x
+= 0.1*(this.tox-this._x);

   this._y +=
0.1*(this.toy-this._y);
//点MC["p"+i] 向目标坐标移动,
移动步长为0.1*(目标坐标 - 当前坐标);

//越接近目标,步长越小。最终,当前坐标=目标坐标,不再移动。


  };

}

}

function
getShape(shape) {
//用shape的值作为判断图形的依据

var R:Number = 100;

var angle:Number =
Math.random()*360*Math.PI/180;

switch (shape)
{
//====================直线======================


case 0 :

  PS[0] = -R+random(R*2);

  PS[1] = 0;

  break;
//====================圆======================


case 1 :

  PS[0] =
R*Math.cos(angle);

  PS[1] =
R*Math.sin(angle);

  break;

}

}


可变化的图形越多,这个程序的观赏性越强

下面补充一些图形,把他们加入switch语句中即可:
var R:Number = 100;

var angle:Number = Math.random()*360*Math.PI/180;

十字

  switch (int(Math.random()*2))
{

  case 0 :

   PS[0] =
-R+random(R*2);

   PS[1] =
0;

   break;

  case 1 :

   PS[0] =
0;

   PS[1] =
-R+random(R*2);

  }


三棱形
  var
r = R*Math.cos(3*angle);

  PS[0] =
r*Math.cos(angle);

  PS[1] =
r*Math.sin(angle);


蝶形

  PS[0] =
R*Math.cos(angle);

  PS[1] =
R*Math.sin(2*angle);


正方形

  RanLine = int(random(4));

  switch (RanLine) {

  case 0 :

   PS[0] =
-R+random(R*2);

   PS[1] =
-R;

   break;

  case 1 :

   PS[0] =
-R;

   PS[1] =
-R+random(R*2);

   break;

  case 2 :

   PS[0] =
R-random(R*2);

   PS[1] =
R;

   break;

  case 3 :

   PS[0] =
R;

   PS[1] =
-R+random(R*2);

  }


同心圆

  lary = random(4);

  PS[0] =
lary*40*Math.cos(angle);

  PS[1] =
lary*40*Math.sin(angle);


螺旋形
  A
= 3;

  r = A*angle;

  PS[0] = 7*r*Math.cos(r);

  PS[1] = 7*r*Math.sin(r);


心形
  var
r = R*Math.cos(angle)-R;

  PS[0] =
r*Math.cos(angle);

  PS[1] = r*Math.sin(angle);


V字
  PS[0]
= -R+random(2*R);

  PS[1] = -R+Math.abs(PS[0]);


Flash充电:switch语句

1.作用:Switch语句代替if/else的嵌套结构,解决多重选择的问题,让语法更清楚简单。


2.说明:在switch语句中,我们可以将case-break视为次单元。除了default之外,每个次单元的
开头都是case,结尾为break,break的作用是跳离本次switch语句。如果某个case次单元没有加上break,则在执行该区段

语句后,
继续往下一个case次单元执行。


3.语法:

switch(键值){

case 条件值1:

  //分段1语句

  break;

case 条件值2:

  //分段2语句

  break;

case 条件值N:

  //分段N语句

  break;
default :

  //默认语句

}

例1:请改变i的设定看看有什么结果?
var i
= 2;

switch (i) {

case 1 :

trace("i=1");

break;

case 2 :

trace("i=2");

break;

case 3 :

case 4 :

trace("i=3 or i=4");

break;

default :

trace("i is not 1,2,3,4");

}

例2:获得键盘键值实例

var listenerObj:Object = new Object();

listenerObj.onKeyDown = function() {

switch (String.fromCharCode(Key.getAscii()))
{

case "A" :

trace("you pressed A");

break;

case "a" :

trace("you pressed a");

break;

case "E" :

case "e" :

trace("you pressed E or e");

break;

case "I" :

case "i" :

trace("you pressed I or i");

break;

default :

trace("you pressed some other key");

break;

}

};

Key.addListener(listenerObj);


教程到此结束
QQ:147461195(FL基理大师)

 

本次课程,对之前学过的画线方法给予总结,同时再加以补充
总结:
圆:

_root.createEmptyMovieClip("MC",1);

MC._x = 200;

MC._y = 150;

var R = 60;

MC.moveTo(R*Math.cos(0),R*Math.sin(0));

MC.lineStyle(2);

for (n=1; n<360; n++) {

var angle = n*Math.PI/180;

var tox = R*Math.cos(angle);

var toy = R*Math.sin(angle);

MC.lineTo(tox,toy);

}

椭圆:

_root.createEmptyMovieClip("MC",1);

MC._x = 200;

MC._y = 150;

var W = 50;

var H = 30;

MC.moveTo(W*Math.cos(0),H*Math.sin(0));

MC.lineStyle(2);

for (n=1; n<360; n++) {

var angle = n*Math.PI/180;

var tox = W*Math.cos(angle);

var toy = H*Math.sin(angle);

MC.lineTo(tox,toy);

}

螺旋线:
_root.createEmptyMovieClip("MC",1);

MC._x = 200;

MC._y = 150;

var R = 10;

var A = 3;

MC.moveTo(0,0);

MC.lineStyle(2);

for (n=1; n<360; n++) {

var angle = A*n*Math.PI/180;

var tox = angle*R*Math.cos(angle);

var toy = angle*R*Math.sin(angle);

MC.lineTo(tox,toy);

}

多边型:
_root.createEmptyMovieClip("MC",1);

MC._x = 200;

MC._y = 150;

var R = 50;

var sides = 5;

var angle = (360*Math.PI/180)/sides;

var MA:Array = new Array();

for (i=0; i<=sides; i++) {

MA[i] = i*angle;

}

MC.moveTo(R*Math.cos(MA[0]),R*Math.sin(MA[0]));

MC.lineStyle(2);

for (n=1; n<=sides; n++) {

var tox = R*Math.cos(MA[n]);

var toy = R*Math.sin(MA[n]);

MC.lineTo(tox,toy);

}


补充:

长方形:

_root.createEmptyMovieClip("MC",1);

MC._x = 200;

MC._y = 150;

var R = 60;

MC.moveTo(0,0);

MC.lineStyle(2);

MC.lineTo(R*2,0);

MC.lineTo(R*2,R);

MC.lineTo(0,R);

MC.lineTo(0,0);

同心圆(与圆对比):
_root.createEmptyMovieClip("MC",
1);

MC._x = 200;

MC._y = 150;

var R = 30;

var layer = 5;
//圆的层数
MC.lineStyle(2);

for (i=1; i<=layer; i++) {

MC.moveTo(i*R*Math.cos(0),
i*R*Math.sin(0));

for (n=1; n<360; n++) {

  var angle = i*n*Math.PI/180;

  var tox = i*R*Math.cos(angle);

  var toy = i*R*Math.sin(angle);

  MC.lineTo(tox, toy);

}
}

蝶形(与圆对比):
_root.createEmptyMovieClip("MC",
1);

MC._x = 200;

MC._y = 150;

var R = 60;

MC.moveTo(R*Math.cos(0), R*Math.sin(0));

MC.lineStyle(2);

for (n=1; n<360; n++) {

var angle = n*Math.PI/180;

tox = R*Math.cos(angle);

toy = R*Math.sin(angle*2);

MC.lineTo(tox, toy);

}

多棱形(与圆对比):
_root.createEmptyMovieClip("MC",
1);

MC._x = 200;

MC._y = 150;

var sides = 5;
//棱数:应为奇数

var R = 100;

MC.moveTo(R*Math.cos(0), R*Math.sin(0));

MC.lineStyle(2);

for (n=1; n<360; n++) {

var angle = n*Math.PI/180;

var
r =
R*Math.cos(sides*angle);
tox =
r*Math.cos(angle);

toy = r*Math.sin(angle);

MC.lineTo(tox, toy);

}

星形(与多边形对比):
_root.createEmptyMovieClip("MC",
1);

MC._x = 200;

MC._y = 150;

var R = 50;

var sides = 5;

var angle = (360*Math.PI/180)/sides;

var MA:Array = new Array();

for (i=0; i<=sides; i++) {

MA[i] = 2*i*angle;

}

x = R*Math.cos(MA[0]);

y = R*Math.sin(MA[0]);

MC.moveTo(x, y);

MC.lineStyle(2);

for (n=1; n<=sides; n++) {

var tox = R*Math.cos(MA[n]);

var toy = R*Math.sin(MA[n]);

MC.lineTo(tox, toy);

}

心形(与圆对比):
_root.createEmptyMovieClip("MC",
1);

MC._x = 200;

MC._y = 150;

var R = 60;

MC.lineStyle(2);

for (n=1; n<360; n++) {

var angle = n*Math.PI/180;

var r =
R*Math.cos(angle)-R;
tox =
r*Math.cos(angle);

toy = r*Math.sin(angle);

MC.lineTo(tox, toy);

}


教程到此结束
QQ:147461195(FL基理大师)


思路:1.使用setInterval计时器,不断调用复制星星的函数;


    
2.每颗星星被创建后,不断减小其自身的_alpha直至0。
步骤1:


  
绘制星形,保存为影片剪辑,连接—>导出—>标志符"star"。

步骤2:

加入AS代码:

var n:Number =
0;

//初始化,复制影片的记数器n

setInterval(CreateStar, 200);

//每200毫秒,调用一次函数CreateStar()

function
CreateStar() {

p =
_root.attachMovie("Star", "Star"+n,
n);
//用指针p指向,复制出的影片"Star"+n,此时p就等于"Star"+n

p._x =
random(400);

p._y =
random(200);
//随机设置当前p所指的影片的坐标

p.onEnterFrame = function()
{
  //”Star”+n的onEnterFrame中不断降低该影片的_alpha直至0

  this._alpha
-= 5;
  if
(this._alpha<0) {

   this.removeMovieClip();


   delete
this.onEnterFrame;
   //影片的_alpha小于0时,影片就没有存在的意义了,直接删除这个影片

  }


};
n++;


}

注意:

 


MC.onEnterFrame =
function() {

this._x += 2;

this._y += 3;

this._rotaion +=
3;

};
//this指的就是MC,也就是调用这个函数的实例名。


实例2:

思路:按照实例1的方法,如法炮制,只改为鼠标经过,再多加些效果而以。

步骤1:

   
绘制星形,保存为影片剪辑,连接—>导出—>标志符"star"。

步骤2:

加入AS代码:

var n:Number =
0;
onMouseMove = function ()
{

p = _root.attachMovie("Star", "Star"+n, n);

p._x = _xmouse;

p._y =
_ymouse;
p.onEnterFrame = function()
{

  this._rotation +=
5;

  this._xscale += 5;

  this._yscale +=
5;
  this._alpha -=
5;

  if (this._alpha<0) {

   this.removeMovieClip();


   delete
this.onEnterFrame;

  }

};

n++;

};
//与实例1不同处用红字标出,不再加以说明。

 

实例3:变幻线

思路:1.两个空MC之间连线。

    
2.每个点都有各自的MC.onEnterFrame,在不停的移动;

    
3.用_root.onEnterFrame 连接舞台中各点。

var num:Number = 5;
//点的个数

var StageW = Stage.width;

var StageH =
Stage.height;
//舞台的宽度(StageW),舞台的高度(StageH)


for (i=0; i<num;
i++) {

p = _root.createEmptyMovieClip("dot"+i, i);

p._x =
random(StageW);
p._y =
random(StageH);
//随机分配该点的X,Y坐标


p.xspeed =
10+int(random(20));

p.yspeed =
10+int(random(20));
//xspeed:向x方向移动的速度;yspeed:向y方向移动的速度


p.onEnterFrame =
function() {

  if (this._x<=0 ||
this._x>=StageW) {

   this.xspeed
*= -1;

  }

  if (this._y<=0 ||
this._y>=StageH) {

   this.yspeed
*= -1;

  }
//判断是否出了上下左右界,若出界,运动方向为反向(乘以-1)


  this._x +=
this.xspeed;

  this._y += this.yspeed;

};
}

_root.onEnterFrame = function() {

_root.createEmptyMovieClip("line", -1);

with (line) {

  lineStyle(2, 0x0f00ff);

  moveTo(dot0._x, dot0._y);

  for (n=1; n<num; n++)
{

   lineTo(_root["dot"+n]._x,
_root["dot"+n]._y);

  }

  lineTo(dot0._x, dot0._y);

}

};
//连接每个点


教程到此结束
QQ:147461195(FL基理大师)

 

本课中的内容涉及:函数定义,
for...in 语句, .onEnterFrame 三个关键内容

函数的作用是实现代码的重用,配合for...in语句可批量赋予函数.

望初学者仔细阅读

思路:1.使用for...in语句遍历整个主场景(_root)中所有的对象;
   
2.找到他们(如_root[k]),并为他们的不同方法指定不同函数;
步骤1:

  
在主场景放入若干个影片剪辑,不需要为他们起实例名。
步骤2:
加入AS代码:

var F1:Function =
function () {

this.startDrag(true);

};

var F2:Function = function () {

this.stopDrag();

};

var F3:Function = function () {

this._rotation += this.speed;

};
//定义三个函数:

// F1完成对象开始拖拽功能;

// F2完成对象停止拖拽功能;

// F3完成对象自转功能,速度为每个对象各自的speed*/

for (var k in
_root) {

_root[k].speed = random(20);

_root[k].onPress = F1;

_root[k].onRelease = F2;

_root[k].onEnterFrame = F3;

}
//遍历主场景,为每个MC设置speed属性及onPress,onRelease.onEnterFrame方法。

 

Flash充电1:两种定义函数的方法
(1)函数语句定义法:如


function Testadd(a, b) {

return a+b;

}

(2)函数表达式定义法:如

var Testadd:Function = function (a, b) {

return a+b;

};
平时,应当尽量使用函数语句定义[方法1],这种定义方法更加标准,也更简捷。


区别:方法2,需要先定义、后调用;

    
方法1,可以先调用,后写定义。


Flash充电2:for...in
用来枚举一个集合中所有的元素

多用于遍历(检索)如:XML,数组,Object甚至_root或MC等等,功能非常强大。
本课中,我们用它来遍历整个_root。

例1:

var Car = {brand:"M6", color:"red", engine:2000};

for (var k in Car) {

trace(k+"="+Car[k]);

}
// 输出结果:

//  brand=M6

//  color=red

//  engine=2000

例2:

//首先,在主场景中放入四个影片剪辑

for (var k in _root) {

trace(_root[k]);

}
//输出结果:

//_level0.instance4

//_level0.instance3

//_level0.instance2

//_level0.instance1

我们注意到,即使不给_root中的MC命名,FLASH编译器也自动为MC命名的,前面的_level10指该元件的深度为10.

Flash充电3:
.onEnterFrame

(1) onEnterFrame是AS动画和游戏制作的灵魂。

(2) 当我们在主场景第一帧写入onEnterFrame=function(){...}时,
实际上Flash编译器会自动在前面加上_root变为_root.onEnterFrame。

(3)重要:MovieClip.onEnterFrame=function(){...}形式。
   这种形式可以让MC独立地运行onEnterFrame。

例:

//首先主场景上有三个影片剪辑,实例名分别为MC1,MC2,MC3。//


MC1.speed = random(10);

MC2.speed = random(10);

MC3.speed = random(10);

MC1.onEnterFrame = function() {

MC1._rotation += MC1.speed;

};

MC2.onEnterFrame = function() {

MC2._rotation += MC2.speed;

};

MC3.onEnterFrame = function() {

MC3._rotation += MC3.speed;

};
试想一下如果场景有100个这样MC那么写代码的过程是不是太痛苦了啊...呵呵。


我们看看下面一种写法:

function F1() {

this._rotation +=
this.speed;

}

for (var k in _root) {

_root[k].speed =
random(10);

_root[k].onEnterFrame = F1;

}
完成的功能相当于:

MC1.speed =
random(10);

MC1.onEnterFrame =
function() {

this._rotation +=
this.speed;

};

函数中this指:调用该函数的对象(MC1)


教程到此结束
QQ:147461195(FL基理大师)

 

滑块使用范围非常广泛

如:音量控制,播放控制,尺寸控制等等,不胜枚举

思路:1.确定滑块的横向移动范围;
    
2.获得滑块(slider)在控制条(bar)中的相对位置(百分比);
    
3.最后返回一个变量(per),范围在1~100,是唯一的变量输出。

步骤1:
 

1.绘制一长方块,保存为影片剪辑,实例名slider,注册点在中心;

2.绘制一控制条,保存为影片剪辑,实例名bar,注册点在左中;

3.放入一个图片,保存为影片剪辑,实例名为mc.

步骤2:
加入AS代码:
var left = bar._x+slider._width/2;

var right = bar._x+bar._width-slider._width/2;

var bottom = top = bar._y;
//确定slider可移动的左右及上下边界


slider.onPress =
function() {

this.startDrag(true, left, top, right,
bottom);

};


slider.onRelease =
function() {

this.stopDrag();


};

_root.onMouseMove = function() {

var per =
Math.ceil((slider._x-left)/(right-left)*100);
//per(slider在bar中的相对位置)=slider的x坐标 ÷
slider移动的宽度范围
_root.mc._xscale = per;

_root.mc._yscale =
per;
//最后用这个比值再去控制图片的缩放大小


};


slider.onReleaseOutside = slider.onRelease;
//鼠标在外面释放也等同于内部释放的效果

^_^这是个非常有用的实例,我们不防把这个控制条整个存为元件,日后再用的只需要从库中拖出一个就可以了。^_^

Flash充电1:startDrag()

mc.startDrag([固定中心],[left],[top],[right],[bottom])

固定中心:[可选]
一个布尔值,指定可拖动影片剪辑是锁定到鼠标位置中央
(true),还是锁定到用户首次单击该影片剪辑的位置上
(false)。

left,top,right,bottom:[可选]
相对于该影片剪辑的父级的坐标的值,用以指定该影片剪辑的约束矩形。


Flash充电2:取整函数简介

(1)Math.floor:
向下取整,小于等于该数字的最接近的整数。

例如:

Math.floor(12.8) 值为 12

Math.floor(-6.2) 值为 -7

(2)Math.ceil:
向上取整,大于等于该数字的最接近的整数。

例如:

Math.ceil(12.1) 值为 13

Math.ceil(12.01) 值为 13

(3)Math.round:
采用四舍五入方式取整。

例如:

Math.round(365.34) 值为 365

Math.round(20.5) 值为 21

Math.round(-45.5) 值为 -45

Math.round(-45.51) 值为 -46

 

教程到此结束
QQ:147461195(FL基理大师)


万事开头难,我们往往在游戏设计初期都会思考这样一个问题,我要做一个什么样的游戏?这个游戏能给玩家带来什么样

的乐趣?似乎有不少人在这个时候会变得很困惑。希望此文能够对大家有所帮助~同时有不到之处还请指出~希望能和大家

多多交流


  [本文由陔隐的呻吟原创,转载请保持保持文章的完整性,谢谢合作]
 
美国俄亥俄大学的一项研究表明﹐人类所有的行为都是由15种基本的欲望和价值观所控制的。
 
研究人员还进行了更深入的分析﹐他们发现﹐不同的人对这15种基本欲望的要求是不一样的。拿性来说﹐性几乎对每一个

人都是愉悦的﹐但对每一个人的驱动力却
并非一致﹐有的人终其一生沉溺于其中﹐而有的人则在这方面投入甚少。其他欲望也是这样﹐有的人追逐成功﹐有的人淡

薄名利﹐有的人重视亲情和家庭﹐有的人则
是"工作狂"。
 
而对于我们游戏设计者来说,我们面对的是各种各样的人,游戏需要包容这些不同性格和追求的人,需要给他们足够的活

动空间,更重要的是要尽可能的满足他们的
各种欲望。可以说无论是哪一类的游戏产品,只要我们所提供的乐趣能够满足这15种欲望的大多数,或者是充分强调其中

的某一种或几种欲望的话,就足以吸引大
批玩家,同时也要注意的是这15种欲望之中有些指的是人们对某种事物或感觉的排斥,所以在游戏设计的过程当中应该尽

量避免此种不良因素的加入。
  以下是我个人对这15种欲望和游戏策划的关系的理解。如有不足和错误的地方万望海涵
  1.好奇心﹕游戏中存在着各种各样的未知事物,需要玩家自己去探索,显然,他们也很喜欢这样做,因为好奇心的驱

使,所以适当的隐藏一些区域或功能其实是明智的。
  2.食物﹕很可惜,目前还没有可以生产面包的游戏平台出现,所以游戏还暂时无法提供这种服务。不过我们可以想象

一下,两个玩家在玩实况足球,他们约定输得一方就要请吃麦辣鸡腿堡,这样一来赢得那一方就可以得到食物方面的满足

了,呵呵~
  3.荣誉感﹙道德﹚﹕一种用户对公平的环境的需求与游戏设计者对以正当手
段获得利益的玩家的充分肯定和支持,同时也是我们惩罚那些利用非正当手段获得利益的人的主要原因。现在有的个别同

行为了吸引玩家故意设计一些BUG或挂机
的功能,看似玩家的热情高涨了许多,可是伤害的却是更多人的利益。其结果必然是灭亡。
  4.被社会排斥的恐惧﹕被社会排斥的原因有很多,比如各种不备社会肯定的行为,初此之外那就是“软弱”了,所以

让用户们较快的脱离菜鸟行列是明智的。另外无法与其他人有效的沟通也会产生被社会排斥的感觉,所以鼓励玩家多多交

流其实是明智的。
  说句题外话,其实游戏本身确实可以在一定程度上,减轻玩家寂寞的感觉,但此种做法本人并不提倡,游戏只是生活
中的一小部分,奉劝沉迷于游戏中的人,健康游戏,健康生活才能体验到活着的乐趣,现在正是春暖花开的时候,没事多

到太阳底下晒晒,哼个小曲,看看美女什么
的,有益身心健康。
  5.性﹕人类最原始也是最强烈的欲望,这也是种种成人游戏火爆的原因,无须多说。
  6.体育运动﹕胖子们也许体会不到人们对运动的渴望其实是天生的,很遗憾目前多数游戏平台并不需要玩家做剧烈的

运动,这也充分体现了他们的局限性,不过体育类游戏永远是电子游戏产业不可分割的一部分。另外也许手指的运动也可

以起到局部减肥的效果,呵呵。
  7.秩序﹕无序也许会给某些人带来好处,比如用外挂的,公共区用马甲骂人
的等等,这些人也许体会不到人们对秩序的渴望其实也是天生的,而且这对大多数人而言这是很不公平的,同时大批用户

的抱怨游戏环境恶劣,经济系统的失衡也会
带来很严重的负面影响,所以我们要尽可能的建立一个有序的游戏环境。另外与现实逻辑相悖也会使用户产生无序的感觉

,所以尽可能的增加“真实感”其实就是减
轻用户的无序感。
  8.独立﹕一种对自作主张的渴望,不等不承认有些时候我们确实有必要对玩
家的一些行为进行限制,比如物理地图的边界或更常见的必须按照剧情发展和关卡设计来进行游戏等等,这些限制确实是

必要,但如果你有条件提高游戏的“自由度
的话”我想你得游戏会更受欢迎,没有人喜欢被束缚。让玩家以自己的方式进行游戏其实是很吸引人的。
  9.复仇﹕一个人战胜了另一个人,后者在复仇欲望的驱使下不断地加强自己最终战胜了前者,而前者又会去走一个复

仇者的路,这对游戏的好处不须多说,所以要想办法更好的利用这一点。


  
10.社会交往﹕倾诉苦闷,分享快乐,这是人类的本能,让玩家之间的有效交流,在某一程度上可以提高一款网络游戏的

黏着度。
  11.家庭﹕一个温暖的归宿,一个可以依靠的港湾,人类是群居的动物,好多游戏都允许玩家结婚,不过关于虚拟婚

姻争议太多,我也不想对这件事说三道四,我要说的只是这也是提高游戏黏着度的一种方式。
  12.社会声望﹕以正当或不正当的方式取得成功并得到奖励和赞誉,这是非常吸引人的,无论是单机的还是多人在线

的,甚至这时许多玩家完这个游戏的唯一动力。不断地升级,不断地加强自己,玩家们乐此不疲。
  13.厌恶﹕在游戏中可能使玩家产生厌恶感的因素有很多,比如繁琐的操作,不清晰引导,不明确的说明,不礼貌的

玩伴等等,所以我们在设计产品的同时必须要考虑这些可能产生厌恶感的所有因素。注意,这非常重要!
  14.公民权﹕所有用户的权利都应该是平等的,所以要尊重所有用户的权利,包括那些以不正当手段获取利益的人,

而且使用游戏中的BUG是也所有玩家的权利,而消除BUG才是我们的义务。
  15.力量﹕人们对力量的渴望很难估量,这也是产生游戏动力的原因之一,人们希望通过自己的力量来影响别人。这

种欲望也是最原始的,好像最原始的东西都是最强烈也是最有生命力的东西。好好利用这一点,你会成功的。
 这样看来除了“食物”、“运动”这两种欲望我们无法或暂时不能满足玩家之外,人们大多数的欲望都可以通过游戏获
得一定程度上的满足,单从这一点来看我们的发挥空间其实是很大的。接下来的事情就是要在不破还游戏性和游戏的完整

性的前提下不断地在更大程度上满足用户,
同时也要研究我们所面对地用户群对哪一种欲望的需求更强烈,我们就下更大的功夫在这种需求上,以合理的安排有限的

资源。
  人类的所有行为都是缘于这15种欲望,好好利用这一点,祝大家都能做出最牛X的游戏!


在AS 03教程中,我们介绍了关于三角函数基础应用
现在为上次课的内容加以补充和发展
复习一下画圆的方法:x坐标cos(n),y坐标sin(n); n
从0~360的弧度

一、绘制椭圆
对比一下,我们只是把画圆方法中 R
,一分为二。
分成了 W 和 H
分别控制椭圆的宽和高。
_root.createEmptyMovieClip("MC",
1);

MC._x = 200;

MC._y =
200;
//创建一个空影片剪辑,放在舞台中央作为画线容器


var W = 50;

var H = 30;
//椭圆宽:W,椭圆高:H.

MC.moveTo(W*Math.cos(0), H*Math.sin(0));
//设置画线起点

MC.lineStyle(2);

for (n=1; n<360; n++)
{

tox = W*Math.cos(n*Math.PI/180);

toy = H*Math.sin(n*Math.PI/180);

MC.lineTo(tox, toy);

}
//当W=H的时候,画出的就是正圆。

 

二、椭圆分配
  
在学习AS
03教程中我们介绍了多边型的画法,有了这个基础在制作本实例就是小菜一碟啦.^_^

实例1:

步骤1:

  
绘制星形,保存为影片剪辑,连接—>导出—>标志符"star"
步骤2:
加入AS代码:
_root.createEmptyMovieClip("MC", 1);

MC._x = 200;

MC._y = 200;

var Num = 22;
//星星数量

var W = 200;

var H =
100;
//椭圆宽:W,椭圆高:H;当W=H时是正圆

var angle =
(360*Math.PI/180)/Num;
//每等份 =
圆的弧度(360*PI/180)/num份
for (i=0; i<Num; i++)
{
MC.attachMovie("star", "star"+i,
i);

MC["star"+i]._x = W*Math.cos(i*angle);

MC["star"+i]._y =
H*Math.sin(i*angle);
}
//复制num个以ang为距离平均分散到圆中


实例2:

步骤1:
  
绘制星形,保存为影片剪辑,连接—>导出—>标志符"star"
步骤2:
加入AS代码:
var num = 22;
//星星数量
var W = 60;

var H = 30;
//椭圆的宽和高
var
wdir = 1;

var hdir = 1;
//wdir:向宽的方向
//hdir:向高的方向
_root.createEmptyMovieClip("MC", 1);

MC._x = Stage.width/2;

MC._y = Stage.height/2;
//圆心X,Y坐标为舞台的中心

var angle =
(360*Math.PI/180)/num;
//每等份 =
圆的弧度(360*PI/180)/num份
for (i=0; i<num; i++) {

MC.attachMovie("star", "star"+i, i);

}
//复制好星星备用
var
right = Stage.width/2-20;

var left = 20;

var bottom = Stage.height/2-20;

var top = 20;
//设置圆的最宽最窄值:wmax,wmin;设置圆的最高最矮值:hmax,hmin。


_root.onEnterFrame
= function () {

for (i=0; i<num; i++) {

  MC["star"+i]._x =
W*Math.cos(i*angle);

  MC["star"+i]._y =
H*Math.sin(i*angle);

  MC["star"+i]._rotation +=
30;

}
//圆的大小W和H是动态改变的


W += wdir*5;

H += hdir*5;
//不断变化中的W和H
if
(W>right || W<left) {

  wdir *= -1;

}

if (H>bottom || H<top) {

  hdir *= -1;

}
//这两段用来判断出界后向相反方向运动


};

 

三、Sin文字串

步骤1:
  
拖出一个动态文本框,变量名为txt,保存为影片剪辑。
  
在库中右击这个MC文件—>链接—>勾选"为ActionScript
导出"和"在第一帧导出"这两项,"标识符"为"ST".

步骤2:
加入AS代码:
var mytext:String =
"学海无涯苦作舟";

var angle = 180/mytext.length;
//正弦图像(180度)根据字数划分每一份的度数


for (i=0;
i<mytext.length; i++) {

var p:MovieClip = _root.attachMovie("ST", "ST"+i,
i);

p.txt =
mytext.charAt(i);
//逐个取出字符

p._x = 50+65*i;

p._y = 60;
//初始该影片的位置


p.angle =
angle*i;
//定义属性表示初始角度


p.onEnterFrame = function() {

  this.A =
(this.angle)*Math.PI/180;

//角度转换为弧度

  this._xscale =
this._yscale=100+50*Math.sin(this.A);

//根据正弦角度,调整该影片大小,范围从[50~150]

  this.angle += 10;

};

}


教程到此结束
QQ:147461195(FL基理大师)


键盘控制角色移动
思路:1.使用键盘控制mc移动,如:Key.isDown(Key.RIGHT);
   
2.并且约定mc移动的范围:顶,底,左,右。
步骤1:

  
制作一个角色,保存为影片剪辑,实例名为"mc".
步骤2:
AS代码层:
var speed = 12;
//移动速度:每次移动的距离


var top = mc._height/2;

var bottom =
Stage.height-mc._height/2;

var left = mc._width/2;

var right = Stage.width-mc._width/2;

_root.onEnterFrame = function () {

  if (Key.isDown(Key.DOWN)
&& mc._y<bottom) {

   mc._y +=
speed;

  }

  if (Key.isDown(Key.UP)
&& mc._y>top) {

   mc._y -=
speed;

  }

  if (Key.isDown(Key.RIGHT)
&& mc._x<right) {

   mc._x +=
speed;

  }

  if (Key.isDown(Key.LEFT)
&& mc._x>left) {

   mc._x -=
speed;

  }

};

 

Flash充电:获取键盘字符方法
var ml = new
Object();
Key.addListener(ml);

ml.onKeyDown = function() {
  
var kd = Key.getAscii();

         
trace(kd)
}

//给ml这个Object添加一个键盘侦听,ml开始侦听按下Key的AscII码。


教程到此结束
QQ:147461195(FL基理大师)


思路:1.设一个变量,如:friction
用于设置摩擦力;
   
2.mc的移动速度每次乘以摩擦力,当摩擦力=1时,不会改变速度;
    当摩擦力小于1时,如:0.8,速度每次都要打8折,折上折直至零。
步骤1:

  
绘制摇奖盘,保存为影片剪辑,实例名为"mc";

  
绘制出二个按钮,保存为按钮,实例名分别为:"play_btn","stop_btn".
步骤2:
加入AS代码层:
var friction =
1;
//表示摩擦力,当friction=1,没有擦力;friction<1,开始拥有摩擦力


var speed = 70;
//圆盘转动的速度

var go = false;
//go=true,圆盘转动,go=false,圆盘停止;


_root.onEnterFrame
= function () {

if (go)
{

  speed =
speed*friction;
//也可写成speed*=friction


  mc._rotation +=
speed;

}

};

play_btn.onRelease = function() {

go = true;

speed = 70;

friction =
1;

};
//开始按钮


stop_btn.onRelease = function() {

  friction = 0.8;

};
//停止按钮

Flash充电1: onEnterFrame

理解:可以简单地理解成为"实时刷新",FPS(帧频)值影响其刷新速度;
定义:以 SWF
文件的帧频重复调用;
例如:

for(i=1;i<=10;i++){trace(i);}
//运行后立即显示 1~10;

设i初值为1
while(i<=10){trace(i);i++;}
//运行后立即显示 1~10;

设i初值为1
onEnterFrame = function(){
if(i<=10)
{ trace(i) }
 
i++;
};
//运行后间断显示
  1
  2
  3
  4
  5
  6
  7
  8
  9
  10

Flash充电2:摩擦力实现原理
例如:speed=10;

    
friction=0.8;
onEnterFrame=function(){

   
speed=speed*friction

   
trace(speed)
}
显示结果:
10

8

6.4

5.12

4.096

3.2768

2.62144

2.097152

1.6777216

1.34217728

1.073741824

0.8589934592
speed
每一次都在原有的数字上面乘以0.8,也就是原有数字的80%。
speed
减小,且无限趋近于0,实现摩擦力效果

 

教程到此结束
QQ:147461195(FL基理大师)

 

思路:1.首先用AS创造出动态文本框,用于输出文字;
   
2.用计时器,每隔一段时间累加输出下一个字符。
AS代码层:
_root.createTextField("output", 1,
0, 0, 500, 400);

var txt_f:TextFormat = new TextFormat();

txt_f.font = "宋体";
//设置字体

txt_f.color = 0x333333;
//设置文字颜色

txt_f.size = 22;
//设置文字大小

txt_f.bold = true;
//是否加粗

output.setNewTextFormat(txt_f);
//将设置好的属性赋给output


var timer = setInterval(display,
500);
//计时器,每0.5秒调用一次display函数

var txt:String = "输入要显示的字符串";

var i = 0;
//初始化


function
display() {

output.text +=
txt.charAt(i);
//每次文字累加
if
(i<txt.length-1) {

  i++;

} else {

  clearInterval(timer);

}

}
//每隔一段时间输出下一个字符,全部输出后,清除掉计时器

 

Flash充电1:字符串与数组下标相同,都是从0开始的。


Flash充电2:字符串常用方法:
(1)String.charAt :
返回字符串中某个字符

   
s=new String("ABCDE");

     trace(s.charAt(3));

   
//输出结果为"D"

(2)String.charCodeAt
:返回字符串中某个字符的字码

   
s=new String("ABCDE");

   
trace(s.charCodeAt(3));

    
//输出结果为 68 .

   
(3)String.concat:
连接其他字符串

   
a=new String("CAT,");

   
b=new String("PIG,")

   
c=new String("DOG")

   
trace(a.concat(b,c))
    //输出结果为"CAT,PIG,DOG"
.

(4)String.indexOf :
寻找子字符串,并返回指针   

   
s=new String("ABCDEF");

   
trace(s.indexOf("CDE"))
    //输出结果为
2 .

(5)String.lastIndexOf :
并返子字符串最后出现位置的指针   

   
s=new
String("ABCDEFCDE");

   
trace(s.lastIndexOf("CDE")) ;

    //输出结果为
6 .

(6)String.slice
: 撷取字符串   

   
s=new String("ABCDEFGHI");

   
trace(s.slice(3,6)) ;

    //输出结果为
"DEF".

(7)String.split
: 将字符串转成数组  

   
s=new String("Bill,Bob,John,Tom");

   
ss=s.split(",")

    
trace(ss[2])

     //输出结果为
"John".

(8)String.substr
: 撷取字符串

   
s=new String("ABCDEFGHI");

    trace(s.substr(3,4))
;

    //输出结果为
"DEFG".

(9)String.toLowerCase
: 转换为小写字母

    s=new
String("ABCDEFGHI");

    trace(s.toLowerCase())
;

    //输出结果为
"abcdefghi".

(10)String.toUpperCase
: 转换为大写字母

    s=new
String("abcd");

  
trace(s.toUpperCase()) ;

    //输出结果为
"ABCD".


教程到此结束
QQ:147461195(FL基理大师)


1.坐标系:

Flash坐标系与数学坐标系:X轴相同,Y轴相反。

[数学坐标系]
[Flash中的坐标系]

2.角度制与弧度制的转换:

(1)弧度:弧度=角度*PI/180;

(2)角度:角度=弧度*180/PI;

*角度制多用于 ._rotation中

*弧度制多用于 sin(),cos(),atan()... ...

3.正弦、余弦、正切:
1>正弦:Math.sin(n);在Flash中多用其图像性质:


随X增长,Y取值为[0,1,0,-1,0]这个变化是周期性的。  

2>余弦:Math.cos(n);用法基本同上。


随X增长,Y取值为[1,0,-1,0]这个变化是周期性的。

3>正切:Math.atan2(y,x)
多用于求两点间的夹角。


Math.atan2(y,x)与Math.atan(n)功能相同只是返回值有所不同:

atan2(x,y)的返回值为一个数字

    atan(n)的返回值从
-PI/2 ~ PI/2


<<<
以上是一些理论知识,下面来看一些具体的应用实例
>>>
4.正弦实例:

思路:使用sin(n)控制mc的Y轴坐标
步骤1:

   
制作一个球型,存为MC,实例名为"Ball",放入舞台中。
步骤2:
加AS入代码层:
var A =
80;
//设置振幅

var centerY = 150;
//设置显示位置

var n = 0;
//累加变量

onEnterFrame =
function () {

ball._y =
centerY+A*(-1*Math.sin(n*Math.PI/180));
//改变ball的y坐标,呈现正弦震动


n += 10;

};


5.正切实例:

思路:使用tan2(x,y)求夹角,通过得出的夹角改变
mc._rotation。
步骤1:

   
绘制出眼,鼻,嘴作为背景;

   
画一个黑色圆作为眼珠,存为MC,实例名为"Reye",注册点在左中。

   
复制一个Reye,实例名为"Leye"作为另一个眼珠。
步骤2:
加AS入代码层:
Reye.onMouseMove = function()
{

var dx = _xmouse-this._x;

var dy =
_ymouse-this._y;
//获得鼠标与眼球的距离


var theta =
Math.atan2(dy,
dx);
//求夹角(弧度制)

this._rotation =
theta/Math.PI*180;
//转换为角度制


};

Leye.onMouseMove =
Reye.onMouseMove;
//Leye鼠标移动时的函数等于Reye鼠标移动时的函数


6.正弦和余弦综合实例:
1>画圆方法:


用cos(n)作为点x,x点从1~0~-1~0

 

用sin(n)作为点y,结合点x,[1,0]~[0,1]~[-1,0]~[0,-1]~[1,0]
沿着, X轴=cos(n),
Y轴=sin(n)的路线绘制出圆
1>AS画圆(重要):
思路:1.创建一个空的影片剪辑作为绘图的容器,在该影片剪辑中进行绘图;
   
2.角度(n) 从 0度到360度 递增;
   
3.X坐标为cos(n), Y坐标为sin(n); n
要为弧度制表示;
_root.createEmptyMovieClip("MC",
1);

MC._x = 200;

MC._y =
200;
//建一个空影片剪辑,并放入舞台中部,作为绘线的容器


var R =
60;
//圆的半径
MC.moveTo(R*Math.cos(0),
R*Math.sin(0));
//开始画线的起点

MC.lineStyle(2);

for (n=1; n<360; n++)
{

angle = n*Math.PI/180;

tox =
R*Math.cos(angle);

toy =
R*Math.sin(angle);
//圆的参数方程

MC.lineTo(tox, toy);

}

2>AS画正多边型(重要):
思路:1.多边形内角和等于360度;
   
2.根据边数,确定每个顶点的角度;
   
3.再根据角度确定每个顶点的位置,并连接各顶点。
_root.createEmptyMovieClip("MC", 1);

MC._x = 200;

MC._y = 200;

var R = 50;
//半径

var sides = 5;
//多边型边数

var angle =
(360*Math.PI/180)/sides;
//每等份 =
圆的弧度(360*PI/180)/sides份;

MC.moveTo(R*Math.cos(0),
R*Math.sin(0));
//绘制起点方在第一个角度上

MC.lineStyle(2)

for (n=1; n<=sides; n++)
{

var tox = R*Math.cos(n*angle);

var toy = R*Math.sin(n*angle);

MC.lineTo(tox,
toy);
//两点间连线

}

3>AS画螺旋线方法(阿基米德螺旋线):
思路:
1.利用极坐标知识;
2.阿基米德螺线的极坐标方程:
Ru(极径)=a(偏移量)*θ(极角);
3.可以简单理解为一个半径在不断增长的圆。
_root.createEmptyMovieClip("MC", 1);

MC._x = 200;

MC._y = 200;

var R = 10;
//半径长度

var a = 3;
//偏移量

MC.moveTo(0, 0);
//从圆心点开始绘制

MC.lineStyle(2);

for (n=1; n<360; n++)
{

var angle = a*(n*Math.PI/180);

var tox = angle*R*Math.cos(angle);

var toy = angle*R*Math.sin(angle);
//螺旋线的参数方程


MC.lineTo(tox, toy);

}


Flash 充电: 三角函数
  
三角函数是数学中属于初等函数中的超越函数的一类函数。它们的本质是任意角的集合与一个比值的集合的变量之间的映

射。通常的三角函数是在平面直角坐标系中
定义的,其定义域为整个实数域。另一种定义是在直角三角形中,但并不完全。现代数学把它们描述成无穷数列的极限和

微分方程的解,将其定义扩展到复数系。
由于三角函数的周期性,它并不具有单值函数意义上的反函数。
三角函数在复数中有较为重要的应用。在物理学中,三角函数也是常用的工具。


基本初等内容

它有六种基本函数(初等基本表示):
函数名 正弦 余弦 正切 余切 正割余割
正弦函数 sinθ=y/r
余弦函数 cosθ=x/r
正切函数 tanθ=y/x
余切函数 cotθ=x/y
正割函数 secθ=r/x
余割函数 cscθ=r/y
以及两个不常用,已趋于被淘汰的函数:

正矢函数 versinθ =1-cosθ

余矢函数 vercosθ =1-sinθ

同角三角函数间的基本关系式:

·平方关系:

   sin^2(α)+cos^2(α)=1

   tan^2(α)+1=sec^2(α)

   cot^2(α)+1=csc^2(α)

·积的关系:

   sinα=tanα*cosα
cosα=cotα*sinα

   tanα=sinα*secα
cotα=cosα*cscα

   secα=tanα*cscα
cscα=secα*cotα

·倒数关系:

   tanα·cotα=1

   sinα·cscα=1

 
cosα·secα=1 

三角函数恒等变形公式:

·两角和与差的三角函数:

cos(α+β)=cosα·cosβ-sinα·sinβ

cos(α-β)=cosα·cosβ+sinα·sinβ

sin(α±β)=sinα·cosβ±cosα·sinβ

tan(α+β)=(tanα+tanβ)/(1-tanα·tanβ)

tan(α-β)=(tanα-tanβ)/(1+tanα·tanβ)

·辅助角公式:

Asinα+Bcosα=(A^2+B^2)^(1/2)sin(α+t),其中

sint=B/(A^2+B^2)^(1/2)

cost=A/(A^2+B^2)^(1/2)

·倍角公式:

sin(2α)=2sinα·cosα

cos(2α)=cos^2(α)-sin^2(α)=2cos^2(α)-1=1-2sin^2(α)

tan(2α)=2tanα/[1-tan^2(α)]

·三倍角公式:

sin3α=3sinα-4sin^3(α)

cos3α=4cos^3(α)-3cosα

·半角公式:

sin^2(α/2)=(1-cosα)/2

cos^2(α/2)=(1+cosα)/2

tan^2(α/2)=(1-cosα)/(1+cosα)

tan(α/2)=sinα/(1+cosα)=(1-cosα)/sinα

·万能公式:

sinα=2tan(α/2)/[1+tan^2(α/2)]

cosα=[1-tan^2(α/2)]/[1+tan^2(α/2)]

tanα=2tan(α/2)/[1-tan^2(α/2)]

·积化和差公式:

sinα·cosβ=(1/2)[sin(α+β)+sin(α-β)]

cosα·sinβ=(1/2)[sin(α+β)-sin(α-β)]

cosα·cosβ=(1/2)[cos(α+β)+cos(α-β)]

sinα·sinβ=-(1/2)[cos(α+β)-cos(α-β)]

·和差化积公式:

sinα+sinβ=2sin[(α+β)/2]cos[(α-β)/2]

sinα-sinβ=2cos[(α+β)/2]sin[(α-β)/2]

cosα+cosβ=2cos[(α+β)/2]cos[(α-β)/2]

cosα-cosβ=-2sin[(α+β)/2]sin[(α-β)/2]

·其他:

sinα+sin(α+2π/n)+sin(α+2π*2/n)+sin(α+2π*3/n)+……+sin[α+2π*(n-1)/n]=0


cosα+cos(α+2π/n)+cos(α+2π*2/n)+cos(α+2π*3/n)+……+cos[α+2π*(n-1)/n]=0
以及

sin^2(α)+sin^2(α-2π/3)+sin^2(α+2π/3)=3/2

tanAtanBtan(A+B)+tanA+tanB-tan(A+B)=0

部分高等内容:
·高等代数中三角函数的指数表示(由泰勒级数易得):

sinx=[e^(ix)-e^(-ix)]/2

cosx=[e^(ix)+e^(-ix)]/2

tanx=[e^(ix)-e^(-ix)]/[^(ix)+e^(-ix)]

泰勒展开有无穷级数,e^z=exp(z)=1+z/1!+z^2/2!+z^3/3!+z^4/4!+…+z^n/n!+…


此时三角函数定义域已推广至整个复数集。

·三角函数作为微分方程的解:

对于微分方程组 y=-y'';y=y'''',有通解Q,可证明

Q=Asinx+Bcosx,因此也可以从此出发定义三角函数。

补充:由相应的指数表示我们可以定义一种类似的函数——双曲函数,其拥有很多与三角函数的类似的性质,二者相映成

趣。


·特殊三角函数值

a      30`   
45`   
60`   
90`

sina   1/2 
√2/2 
√3/2     1


cosa √3/2 
√2/2  
1/2   
0

tga
√3/3  
1    
√3   不存在

ctga √3     
1   
√3/3   
0

 


教程到此结束
QQ:147461195(FL基理大师)


数字魔方(经典数据结构实例):
1.本游戏的玩法,均在本FLASH中一一介绍了,博客中不再重复:
下载地址:
http://www.flashempire.com/myfe/upload/flash/142/1410014_1195878655.swf
2.编程序的基本原则就是这个游戏玩法的原则即:
1)第一行中间是1;

2)向右1格;向上1格;

3)上边出界,去下边;

4)右边出界,去左边;
5)
没数占着,就填数;

6)有数占着,坐屁股下。

3.下面是矩阵计算的程序:
var n:Number =
5;
//矩阵的行列数为n*n;

var matrix:Array = new
Array();
//因为AS中不能直接调用二维数组,所以我们先申请一个一维数组;


for (var i = 0;
i<n; i++) {

matrix[i] = new Array();

for (var j = 0; j<n; j++) {

  matrix[i][j] = i*n+j;

}

}
//上面这些代码的作用:把一维数组变为二维数组(算是一段功能代码);

for (var i =
0; i<n; i++) {

for (var j = 0; j<n; j++) {

  matrix[i][j] = 0;

}

}
//二维数组初始化,使matrix中的每个元素都为0;


var movei:Number = 0;

var movej:Number = int(n/2);

matrix[movei][movej] =
1;
//这里完成了总体原则的第一步[第一行中间是1];

var counter:Number =
2;
//计数器,准备放入下一个数2

for (i=0; i<n;
i++) {

for (j=0; j<n; j++) {

  tempi = movei--;

  tempj =
movej++;
  //总体原则第2步[向右1格;向上1格]


  if (movei<0) {

   movei =
n-1;
   //总体原则第3步[上边出界,去下边]


  }

  if (movej>n-1) {

   movej =
0;
   //总体原则第4步[右边出界,去左边]


  }

  if (matrix[movei][movej] == 0)
{

   matrix[movei][movej]
=
counter++;
   //总体原则第5步[没数占着,就填数]


  } else {

   movei =
tempi+1;

   movej =
tempj;

   matrix[movei][movej]
=
counter++;
   //总体原则第6步[有数占着,坐屁股下]


  }

}

}
//------------最后输出矩阵看看一看--------------


for (i=0; i<n; i++) {

trace(matrix[i]);

}

 


Flash充电1:在AS中数组的下标和C语言一样,都是从0开始的。
下面看一个实例:
var
myarray:Array=["CAT","DOG","PIG","BIRD","MONKEY"];


trace(myarray[3]);
//测试后显示BIRD

 

Flash充电2:在数据结构中还有两种概念,一个是堆栈,一个是队列。
在AS中这两个概念同样也是用数组来完成的。
堆栈(后进先出):
1.出栈:
pop():提取最后一个元素后,删除该元素
var
myarray:Array=["CAT","DOG","PIG","BIRD","MONKEY"];
trace(myarray.pop())
//显示MONKEY,后删除最后一个元素"MONKEY"
2.入栈:
push():在最后一个元素后,插入一个元素
var
myarray:Array=["CAT","DOG","PIG","BIRD","MONKEY"];
myarray.push("FISH")
trace(myarray)
//显示CAT,DOG,PIG,BIRD,MONKEY,FISH,在最后一个元素后面加一个"FISH"

队列(先进先出):
shift():提取第一个元素后,删除该元素
var
myarray:Array=["CAT","DOG","PIG","BIRD","MONKEY"];
trace(myarray.shift())
//显示CAT,并删除第一个元素"CAT"

Flash充电3:数组常用操作。
var
myarray:Array=["CAT","DOG","PIG","BIRD","MONKEY"];
trace(myarray.length)
//显示5,获取数组长度;
trace(myarray.join("+"));
//显示CAT+DOG+PIG+BIRD+MONKEY,把数组间用"+"连接,当然也可设为其它符号
trace(myarray.reverse());
//显示MONKEY,BIRD,PIG,DOG,CAT,数组倒排序

教程到此结束
QQ:147461195(FL基理大师)


使用方法:
将下列代码写入fla的第一帧;在任意帧中写入delay();命令就可以实现3秒钟延时功效;


思路:
1.使用FPS和onEnterFrame配合完成.
2.Flash动画默认1秒钟播放12帧,即FPS为12。
3.执行一次onEnterFrame(进入帧),counter++自加1,那么一秒钟要加多少次呢?1秒钟要进入12次帧,所以自加了12

次。那么2秒钟,3秒钟呢…于是我们得出公式
总延迟时间 = 延迟秒数 * FPS
原理就是用帧数做延时。
AS代码:
var fps:Number =
12;
//在Flash中默认的fps值为12,如果改动了默认fps值的话这里也要相应改动;
var delaytime:Number =
3;
//延时的秒数;

var counter:Number = 0;
//计数器的初值;

function delay() {

onEnterFrame =
function () {

  if (counter<delaytime*fps) {

   this.stop();


   counter++;


  } else {

   delete
this.onEnterFrame;

   counter =
0;

   this.play();


  }

};

}

 

注意:当该Flash帧动作中有onEnterFrame,要直接在onEnterFrame中输入代码:
var fps:Number = 12;

var delaytime:Number = 3;

var counter:Number = 0;
if (counter<delaytime*fps){

  counter++;

} else {

  counter =
0;

}

 

Flash充电: FPS概念

FPS(Frames Per Second):
即每秒播放帧的数量,Flash中默认值为12,就是说:默认Flash动画是1秒钟播放12帧。

教程到此结束
QQ:147461195(FL基理大师)


思路:声音的播放、停止、暂停的实现,非常简单。
步骤1:
首先放入三个按钮,实例名分别为
“start_btn”“pause_btn”“stop_btn”;
然后再导入一个声音文件到库中;

导入完成后,在库中右击这个声音文件—>链接—>勾选"为ActionScript

导出"和"在第一帧导出"这两项,在给"标识符"中输入一个名字,如"Cannon".

   
步骤2:
加入AS代码层:
var mysound:Sound = new Sound();
//让mysound具有Sound类的属性和方法


mysound.attachSound("Cannon");
//mysound链接到库中名为"Cannon"的声音元件


Start_Point =
0;
//设置播放的起点位置

play_btn.onRelease = function() {

mysound.start(Start_Point/1000);};
//播放按钮:从起点位置开始播放声音,因为要接收秒数,所以要除1000

pause_btn.onRelease = function() {

Start_Point = mysound.position;

mysound.stop();};
//暂停按钮:先保存当前播放到的位置为起点,然后停止播放

stop_btn.onRelease = function() {

Start_Point = 0;

mysound.stop();};
//停止按钮:将起点位置设为0,然后停止播放


Flash充电:Sound类常用属性和方法


(1)Sound.attachSound("idName"):声音对象依附声音元件

   
mysound.attachSound("Cannon")


(2)Sound.start(播放起点,循环次数):开始播放声音

   
mysound.start(5,3)

   
//从5秒钟位置开始播放,循环三次

   
mysound.start()

   
//从0秒钟位置开始播放,循环一次

(3)Sound.stop("idName"):停止播放声音

   
mysound.stop()

   
//停止全部声音

(4)Sound.setVolume(1~100):设定音量

   
mysound.setVolume(50)

   
//设置音量为50

(5)Sound.getVolume():取得音量设定值

   
mysound.setVolume(33)

   
trace(mysound.getVolume())

     //返回33


教程到此结束
QQ:147461195(FL基理大师)


思路:1.设一个pressed变量,为布尔型,初始为false;
    
2.鼠标移动就画线;
    
3.当pressed=true 时,鼠标移动时,可以画线;
    
4.当pressed=false时,鼠标移动时,不能画线;

    
5.最后再加入一些按钮来调整线条粗细和清空画板.
步骤一:

  
放入三个按扭,实例名分别为:

    "clear_btn":
清除线条;

    "str_btn":
加粗线条;

    "thin_btn":
减细线条。
步骤二:
加入AS代码层:
var linesize
= 2;
//默认线条粗细为2

var pressed:Boolean =
false;
//pressed=true:开始画线;
pressed=false:停止画线


str_btn.onRelease =
function() {

if (linesize<5) {

  linesize++;
//笔触加粗,粗度不能大于5
}


};


thin_btn.onRelease
= function() {

if (linesize>1) {

  linesize--;
//笔触减细,细度不能小于1
}


};


clear_btn.onRelease
= function() {

_root.clear();
//实现清屏功能

};


this.onMouseDown = function () {

pressed =
true;
this.lineStyle(linesize,
0x000000, 100);

this.moveTo(_xmouse, _ymouse);

};

this.onMouseMove = function () {

if (pressed) {

  lineTo(_xmouse, _ymouse);

}

};

this.onMouseUp = function () {

pressed =
false;

};

 

FLASH充电1:AS画线,既可以在舞台上(_root),也可以在影片剪辑上(mc).

          
推荐画在mc中,这样可以方便、灵活地控制。

FLASH充电2: 关于 lineTo 及
moveTo
(1)先要设置线条用 lineStyle( 粗度 ,
颜色 , 透明度)
(2)画笔的起点 moveTo( X坐标 , Y坐标 )
(3)画笔的终点 lineTo( X坐标 , Y坐标 )
(4)注意:执行完 lineTo
这个指令后,下一次画线的起点就是当前lineTo的位置,就不用再单独做一次moveTo指令了。

下面我们在mc中绘制一个矩形
_root.createEmptyMovieClip("mc", 10);

mc._x = 30;

mc._y = 30;

mc.lineStyle(2, 0x0, 100);

mc.moveTo(0, 0);

mc.lineTo(100, 0);

mc.lineTo(100, 100);

mc.lineTo(0, 100);

mc.lineTo(0, 0);

FLASH充电3: 关于 curveTo ( 控制点X ,
控制点Y , X坐标 , Y坐标 )
下面我们在mc中绘制一条曲线:
_root.createEmptyMovieClip("mc", 10);

mc._x = 30;

mc._y = 30;

mc.lineStyle(2, 0x0, 100);

mc.moveTo(0, 0);

mc.curveTo(0, 200, 100, 200);


FLASH充电4: 颜色填充 beginFill(颜色号)
及 endFill()
注意:填充只能在封闭的线条内进行。
下面为矩形填个绿色:
_root.createEmptyMovieClip("mc", 10);

mc._x = 30;

mc._y = 30;

mc.beginFill(0x00FF00);

mc.lineStyle(2, 0x0, 100);

mc.moveTo(0, 0);

mc.lineTo(100, 0);

mc.lineTo(100, 100);

mc.lineTo(0, 100);

mc.lineTo(0, 0);

mc.endFill();

FLASH充电5: 线条清除
clear()
如:_root.clear() 或 mc.clear()


教程到此结束
QQ:147461195(FL基理大师)


思路:1.隐藏原有鼠标指针;
    
2.鼠标的位置=mc的位置
步骤1:
  
绘制一个鼠标指针,保存为影片剪辑,实例名为"mymouse";

  
该指针也可为动画形式,且指针的中心点位于影片剪辑中心点的右下方;
  
做好后,放到舞台中。
步骤2:
加入AS代码层:
Mouse.hide();
//隐藏默认指针
_root.onMouseMove = function() {

mymouse._x = _xmouse;

mymouse._y = _ymouse;

updateAfterEvent()

};

FLASH充电:updateAfterEvent()
  使用 updateAfterEvent()
继续刷新舞台,使光标的移动看起来顺畅。


教程到此结束
QQ:147461195(FL基理大师)


思路:首先获得系统时间,然后乘以相应的度数,实现钟表的功能。
步骤1:

  
绘制时针(hc),分针(mc),秒针(sc),其中hc,mc,sc是实例名。
步骤2:
加入AS代码:
_root.onEnterFrame
= function () {

var now:Date = new Date();

var hour = now.getHours();

var minute = now.getMinutes();

var second =
now.getSeconds();
//首先获得系统的时,分,秒


hc._rotation = hour*30;

mc._rotation = minute*6;

sc._rotation =
second*6;
//小时:一圈是360度,共12小时,每一小时30度


//分钟:一圈是360度,共60分钟,每一分钟6度

//秒钟:一圈是360度,共60秒钟,每一秒钟6度

};

Flash充电:常用的Date()类方法
(1)Date.getFullYear()//返回形式2007年份
(2)Date.getMonth()//返回形式1~12月份
(3)Date.getDate()//返回形式1~31日期
(4)Date.getDay()//返回形式1~7星期
(5)Date.getHours()//返回形式0~23

(6)Date.getMinutes()//返回形式1~59

(7)Date.getSeconds()//返回形式1~59


教程到此结束
QQ:147461195(FL基理大师)


很多人都叫比自己高的人为高手,凡是比自己强的都是高手,几乎所有的人大概都这么认为,那么什么才是真正的高手呢

有谁真正的去想过?而这个问题比较笼统,也不是那么好说清楚的,我想世界上一流的闪客也不一定能完全说清楚和明白

,因为它涵盖的范围比较广泛与繁多。那么鄙人就现在所知的一点心得写出来,畅聊大家,愿共行商讨。
我现在日益明白,所谓的高手必须具备以下几个素质。

1.技术。拥有精妙的as编程、美妙的美工处理、绝妙的动画制作、玄妙的特效镜头、与神妙的博大内涵文化等。
2.冷静。凡是都比较冷静的去对待,不娇不躁。

3.细心。古人曰:心细如发,才能达到无微不至的境界,做事方可游刃有余,如行云流水。

4.悟性。心思巧妙,善于思考,悟性极佳,一点即透,摸索东西也快。

5.好学。所谓学海无涯,在高手的领域中,永远觉得自己还是沧海中的一黍。

6.勤奋。真正做到了老子说的“上士闻道,勤而行之”的境界。

7.淡泊。不管神游于哪个专业论坛皆能心虚,而不自大、自夸、自满、自以为是,从不在别人面前班门弄斧、显示技巧。

8.热情。人一旦有空、有条件时一定会帮助初学者排忧解难,从不叫别人给他歌功送德,真正达到了“无条件”帮人的楷

模境界。

9.低调。从不在论坛、群里骂别人是“垃圾”,也不会在别人的文章和作品前说他是弱智等,没有热嘲和冷讽,也不会装

模做样的伴酷,恰恰显得平易近人。

10.境界。真正认识到了事物的本质和善恶美丑好坏的最高标准。而不会像那些拥有高超的技术、美工、编程的某某高手
们,做出的东西却是十分的“抽象派”、“黄色派”、“不知所云派”、“乱抹一气派”、“宣扬暴力***派”、“阴阳

怪气派”、“感觉派”、“现代时尚
派”、“无聊派”等等作品出来。

这就是所谓的闪客界的“高手”,也是真正的高手,但一千个人中可能只能有那么一两个吧。

很多人看认为不可思议,觉得做不到,但正因为做不到你才会觉得难、觉得“高”,正因为“高”,才是一种领域,一种

境界,一种高嘛。

这可以说是一种标准,很多人不是全部能达到与做到的,有的人能做到一点点,有的人能做到几点,有的人可能全部能做

到,能全部做到的那就是真正的高手。

 

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值