CGArt-中国CGer中的绿色家园
首页 信息动态 原创排行 互动教程 资源千寻 CG人才 CGArt杂志 艺术设计 CG画廊 CG论坛 酷站欣赏 CG搜索 会员中心
新手来看:Flahs as入门教程
来源:网页教学网 编辑:浪漫的季节 发布时间:2007年11月16日 09:04:42

[ 1 ]  [ 2 ]  [ 3 ]  [ 4 ]  

关于数组的方法(method)

方法就是从属于某一对象(object)的函数,通常都是对该对象进行处理的函数
好象太抽象了?我们还没讲到什么是对象,其实数组是对象的一种,我们就暂且将数组的方法理解为一个专门处理数组内数据的结构和内容的工具吧
例如一个叫push()的方法就是一个工具,用于为数组添加一个元素,并且加在该数组的最后
使用起来并不复杂,看例子就知:
// Create an array with 2 elements
var menuItems = ["home", "quit"];
// Add an element 加一个元素
// menuItems becomes ["home", "quit", "products"]
// 现在数组的结构变成["home", "quit", "products"]
menuItems.push("products");
// Add two more elements 这次是加两个
// menuItems becomes ["home", "quit", "products", "services", "contact"]
menuItems.push("services", "contact");
跟push()相反从最后弹出一个元素的方法是pop()
而跟push()类似,但是是将一个元素加到数组的开头的方法是unshift(),与之相反的是shift()
方法sort和reverse,用于重新排列数组的元素
方法splice用于从数组中间删除某元素
方法slice和concat可以在某些数组的基础上生成另一个新的数组
方法toString和join可以将整个数组变成单一个字符串
以上方法都可以从AS字典里面查到

第十章 第三个版本的选择题
首先,此版本沿用了上一版本的函数answer和gradeUser
在这一版本中,用户的答案与正确答案将使用数组来存放
看看我们的新代码:
stop();
// *** Init main timeline variables
var displayTotal; // Text field for displaying user's final score
var numQuestions = 2; // Number of questions in the quiz
var totalCorrect = 0; // Number of correct answers
// 上一版本中,用户答案使用了两个变量来存放,但是试想如果是10题、100题呢?使用数组将更容易管理,也更容易处理
var userAnswers = new Array(); // Array containing user's guesses 这是定义数组的语句,但是还未输入数据
var correctAnswers = [3, 2]; // Array containing each correct answer 这一句既定义数组,同时输入数据,因为正确答案是已知的
// *** Function to register the user's answers
function answer (choice) {
// Tack the user's answer onto our array 将数据PUSH进数组,因为是顺序答题,所以用方法PUSH
userAnswers.push(choice);
// Do a little navigation, baby
// 如果答案数超过题目总数,自然就跳到quizEnd帧了
// 注意在本例中,已经不用上例的answer.currentAnswer而是使用userAnswers.length来控制问题是否结束
// 我们甚至可以用correctAnswers.length来代替numQuestions,记录正确答案数组的长度,不就是题目总数吗?
if (userAnswers.length == numQuestions) {
gotoAndStop ("quizEnd");
} else {
gotoAndStop ("q"+ (userAnswers.length + 1));
}
}
// *** Function to tally the user's score
function gradeUser() {
// Count how many questions were answered correctly.
// 开始改题,这里就不用再用上个版本的eval啦,那个东东实在是难懂兼难用,这个版本相对就很清晰明快
for (var j = 0; j < userAnswers.length; j++) {
if (userAnswers[j] == correctAnswers[j]) {
totalCorrect++;
}
}
// Show the user's score in a dynamic text field
displayTotal = totalCorrect;
}
电影的其他部分不用改动(这就是使用FUNTION的好处啦,升级多快~)
OK,进入下一章之前想想目前版本的点
* 题目,每次修改题目都要进入FLASH的场景修改,麻烦
* 按钮,每题就要做三个按钮
这都是麻烦的地方,我们要更精益求精地修改,让我们的多选题,轻易地从两题变成10题、100题
接下来我们要做的是
* 进一步改进我们存放数据的结构
* 让我们可以动态地生成每一道题目,只需输入数据,而不需要在FLASH里面作就可以自动生成
所以——我们需要面向对象编程!(object oriented programming)
chocobo:嘻嘻,众菜鸟是不是都倒了,AS基础教程竟然开始讲OOP了,呵呵,没关系啊,上面的教程一直都这么浅,以后也深不了
第十一章 一点面向对象编程知识
At is heart, OOP simply means that you treat portions of your program as self-contained, but interrelating modules called objects.
这是什么呀?我不翻译了,概念的我们就先不懂吧,对象主要构成包括属性(properties)和方法(methods)
一个对象通常都以现实世界里的某个东东做蓝本
例如我们可以定义一个对象叫球
那么这个球将会有这样的属性:半径、X坐标、Y坐标、颜色
同时,也会用属于球自己的方法例如:移动球、计算球的面积
当然,我们还可以定义一些相对抽象的对象,例如我们要做的多选题
所有的对象都属于某类(class),类的意思其实是用于创建对象的模版
一个实例(instance)就是某一个类的特定某一个case(好复杂,概念性的东西我翻不过来啦,反正实例就类创建出来的某一个对象)
还是再举例吧
* 例如我们有个一个叫Chair的类
* 这个类定义了一个东西需要它有四条腿,一个坐垫
* 然后我们就可以用Chair这个类来定义我们的不同对象(可理解为椅子的款式),每个对象就有它特有的高、宽、材料、重量、颜色,正是这些属性使每个对象互相区别。
所有的椅子互相区别,有自己的属性,但是他们又有同样的结构:四条腿、一个坐垫
OK,那AS里面的类和对象呢?
是的,AS里我们可以自己创建对象,也有可以使用的内建对象
内建的类(你可以用它来创建对象)包括:Array, Boolean, Color, Date, MovieClip, Number, Object, Sound, String, XML, XMLSocket
内建的对象(已经可以直接使用的对象)包括:Arguments, Key, Math, Mouse, Selection
内建的类、对象当然都是在FLASH里面有自己功能的东西。而正是这些功能非常常用,FLASH才内建了这些类和对象,例如:
Mouse.hide(); // Hide the mouse pointer 将鼠标隐藏,你经常用吧?现在才知道其实是内建的Mouse对象的一个hide()方法吧?
在学习如何创建自己的类和对象之前,先来了解一下内建类和对象是怎样工作的吧
与数组的结构类似,对象是容器们(containers)的容器(container)
一个对象,用各个独立的属性来存放数据,只不过数组区分每个容器是用数字,而对象则是用属性名,要调用一个数组里面某个数据,我们需要它是索引值,而要调用对象的属性,则要知道属性名
看看以下这个例子,这是个叫BALL的对象“
BALL对象有两个属性:radius 和 color
而两个属性分别赋值为:50 和 0xFF0000 (这是AS里面表达16进制的方法)
概念清楚了,说一AS里面使用对象要注意的地方
首先,对象的属性很灵活,它储存的数据可以是strings(字符串), numbers(数字), booleans(布尔值), null(空), undefined(未定义), functions(函数), arrays(数组), movie clips(电影夹子), or even other objects(甚至是其他的对象,包括自定义的).
调用属性,可用点语法:objectName.propertyName
例如我们赋值给BALL里面的属性radius:
ball.radius = 100;
我们也可以用符号&#;来访问属性,但是&#;里面的属性名需用双引号扩住,同上例:
ball["radius"] = 100; (所以说数组也是对象一种,访问方法也一样,并没有搞特殊化)
与点语法比较,&#;更灵活,可以动态地改变属性的名字,里面可以是变量或表达式,例如:


var propName = "radius";
ball[propName] = 100;
这点是点语法无法办到的
纯粹的OOP中,我们几乎不会直接访问对象的属性
我们一般都使用方法(methods) ,来改变属性
例如改变mySound这个声音对象的音量属性
AS的用法应该是mySound.getVolume(100);
而不是mySound.volume=100;
但是为了简单,多选题这个例子里不一定遵循这个原则,事实上AS里面很多对象都不可以办到这点,所以有人说AS不是面向对象语言。
关于对象的方法
方法method其实是一些附属于对象的函数,其作用主要是访问对象中的数据,或完成某种功能
所以调用方法和调用普通函数类似:objectName.methodName() 只是前面加上了对象的名字
例如上面的BALL对象,我们需要它的面积,使用 getArea 这个方法:
ball.getArea();
预习一下,在下一个例子中,虽然MOOCK不打算建立自己的方法,但是将使用内建于MovieClip对象的两个方法:
*MovieClip.attachMovie()
此方法是将Library(CTRL+L按出来的那个)里面的symbol复制一个instance到场景中
(chocobo:给不懂概念的人紧急补习,放在库(Library)里面的叫符号(symbol),拉到场景中就叫实例(instance),一个符号可创建多个实例,符号改变则实例随之改变)


与之类似的是MovieClip.duplicateMovieClip(),但是该方法需要事先在场景里已经有一个实例
*MovieClip.removeMovieClip()
此方法与上面相反,是删除场景里面的instance的
大家看到了,在下一例中,我们将使用MovieClip这个内建对象,因为它就可以满足我们的需要,不必新类型的对象了
我们先来熟悉一下MC这种对象
它有很多属性_height(高度)、 _alpha (透明度),MC的属性大家可以在AS字典里面查到,在AS面板里这写属性也是变色显示的
同时MC的方法,例如 MC.play(); 等也可以查到
当我们在MC里面的时间线使用这些属性、方法的时候,可以省略不写前面部分,直接写play();
MC可以互相嵌套,MC当中又有MC,就出现类似: mc1.mc2.play(); 的情况
为了调用包含自己的上一级MC的方法、属性,AS里面用_parent,例如:
在mc1包含mc2 ,在mc2中想使mc1播放:_parent.play();
还有另一个保留字:_root指代该电影的主时间线
例如想在某个mc里面让整个电影播放:_root.play();
想在某个MC中让另一mc1播放:_root.mc1.play();
还有,MC中定义的变量,将作为MC的一个属性可被访问
在mc1里面写了一句 var a=1;
我们将可使用 mc1.var来调用它

 


关于类(class)
这个概念大家还是不大懂吧?类就是定义一个对象将拥有什么的方法跟属性的东东,类似MC里instance与symbol的关系,instance的结构就是由symbol决定的,每个instance又可以不一样
AS里面没有专门定义类的例如class这样的关键字,我们使用函数来定义类,这种函数称构造函数constructor function,函数的作用就是产生我们定义好的类的实例(就是对象)
举例最实在:
// make a Ball constructor 最简单的构造函数
function Ball () {
// do nothing 里面是空的
}
现在我们可以定义新类型Ball的对象了
myBall = new Ball();
语法就是前面是新对象实例名,等号后是new加构造函数名
myBall就拥有了Ball定义的一切结构了(虽然Ball里面是空的,嘻嘻)
不过不是所有对象创建都用new,例如mc创建就用的是attachMovie()或duplicateMovieClip()
好了,我们的构造函数总不能空的,如何定义类,让新对象有自己的属性呢?
使用this这个关键字,看例子,新的构造函数:
function Ball () {
this.radius = 10;
this.color = 0xFF0000;
this.xPosition = 35;
this.yPosition = -4;
}
以后我们定义出来的新对象,都拥有半径,颜色、XY坐标属性啦
慢着,怎么每个新对象都一模一样啊?
再改,用函数的参数来定义动态的属性:
// Make the Ball constructor accept
// property values as arguments.
function Ball (radius, color, xPosition, yPosition) {
this.radius = radius;
this.color = color;
this.xPosition = xPosition;
this.yPosition = yPosition;
}
我们可以定义不同属性的对象了
myBall = new Ball(6, 0x00FF00, 145, 200);
本教程关于还有创建方法以及如何在类之间继承方法和属性没讲,
无论如何,OOP都不可能在这么短时间之内说清楚,
但这不妨碍我们做下一个例子了。

第十二章 第四个版本的选择题
第三个版本的时候我们已经设想好,新版本中题目将是动态生成的,不用我们在FLASH的场景里面一题一题输入了,我们要做的只是输入题目和题目答案的数据就够了。
很明显,每一条题目都将是一个对象(不然我们学这么多对象的知识干嘛?),而这些所有的题目,会用一个数组来存放
再重提一下,可配合源程序学习 http://www.moock.org/webdesign/lect...oockQuizzes.zip ;
好,开始设计题目的模版
模版就是一个MC,包含两个TEXT FIELD,里面不用填东西,分别起变量名为:(FOR小鸟:TEXT FIELD就是按工具条里T按钮拉出来的文本框,同时还要在文本面板(ctrl+t)里将其改为Dynamic Text,变量名则在面板的Variable处改)
* qNum (以后将显示题目的编号)
* qText (以后将显示题目的正文)
我们还要在库里面做标识,点一库面板(ctrl+l)右上的Options>> Linkage ,选第二个Expert this symbol,identifier填上questionTemplate,至此,题目模版完成
再制作选项的模版
选项模版应包括一个选择用的按钮
还有该选项的内容,一个起名为answerText的TEXT FIELD
在本例的后面,将为每一个动态生成的选项一个唯一的名字,譬如: "answer0", "answer1",..."answern".
答题者所选定的答案将由这个名字来决定,调用一个MC的名字,用的是_name这个属性
所以答题的按钮上面的AS为:
on (release) {
// Trim the prefix "answer" off this clip's name
// 下面使用了String.slice()方法,例如_name为answer0,它将被处理成0,slice的具体语法请查阅AS字典
// 按钮提交什么由该MC的名字决定的,我作个标记 @@ ,记得一会看回来
choice = _name.slice(6, _name.length);
// 与前面的例子一样,最后将答案提交给answer函数处理,不过现在我们是在某一MC里面用外面主时间线的函数了,所以得加上_root
_root.answer(choice);
}
最后,Options>> Linkage,标识名:answerTemplate,制作模版的工作就完成了
下面将是放在第一帧的程序主体,可要打起精神来了:
// Stop the movie
stop();
// Init main timeline variables
var displayTotal; // Text field for user's final score
var totalCorrect = 0; // Number of questions answered correctly

 


// Array containing the user's guesses 记录作答答案的数组
var userAnswers = new Array();
// Number of the question the user is on 记录正在作答中题目的编号
// 要注意的是,它是由0开始的,第一题的编号是0,因为我们要用到数组,数组的第一个编号是0,所以这里我们也用0
var currentQuestion = 0;
// The Question constructor
// 以下是新类型对象question的构造函数,包含三个属性:正确答案,题目正文,各个选项
function Question (correctAnswer, questionText, answers) {
this.correctAnswer = correctAnswer;
this.questionText = questionText;
this.answers = answers;
}
// Import the source file containing our array of question objects
// 咦?应该是输入各条题目的数据先啊,放哪去了?因为嘛,数据输入是个与编程无关的过程,为了让代码更优雅,这些繁琐的东西扔别地方去了,AS太长,会使查阅相当麻烦,分开存放也是好习惯!
// #include是引用外部AS命令,可以将AS分开储存于各个后缀名为AS的文件中,输入题目的代码就是放到了questionsArray.as中(记得和FLA放在同一目录下喔)
#include "questionsArray.as"

 


//// 我改变了一下教程的结构,把questionsArray.as的内容也插入进来了,因为跳过这段的话,看起来会有疑问
//// 以下内容系存放questionsArray.as中的
// 输入数据其实是建立对象
// MOOCK用一个数组还存放这些对象,这样对象才更易于管理
// 不要被括号给弄昏了,输入对象参数的中间还有中括号,是因为输入题目的参数“各个选项”是一个数组
// 因为是存放于数组中,每个对象之间记得应有逗号分隔
// Remember to place a comma after each object
// in the array except the last
questionsArray = [new Question (2,
"Which version of Flash first introduced movie clips?",
["version 1", "version 2", "version 3",
"version 4", "version 5", "version 6"]),
new Question (2,
"When was Action formally declared a ing language?",
["version 3", "version 4", "version 5"]),
new Question (1,
"Are regular expressions supported by Flash 5 Action?",

 


["yes", "no"]),
new Question (0,
"Which sound format offers the best compression?",
["mp3","aiff", "wav"]),
new Question (1,
"True or False: The post-increment operator (++) returns the
value of its operand + 1.",
["true", "false"]),
new Question (3,
"Action is based on...",
["Java", "Java", "C++", "ECMA-262", "Perl"])];
//// 离开questionsArray.as部分,我们继续
// Begin the quiz 出题目!调用makeQuestion函数来完成,我们只需要给这个函数一个参数:题目的编号,函数就会按编号提取数据,结合我们刚才做的模版生成题目。
makeQuestion(currentQuestion);
// Function to render each question to the screen
// 下面就是makeQuestion函数
function makeQuestion (currentQuestion) {
// Clear the Stage of the last question
//这句是清理上一题生成的MC,这句从第二题开始生效,questionClip就是题目的MC名,MC从哪来的?看下面就知道了

 


questionClip.removeMovieClip();
// Create and place the main question clip
// 利用模版questionTemplate生成一个叫questionClip的MC,这个MC就是我们的问题
attachMovie("questionTemplate", "questionClip", 0);
// 设定MC的位置
questionClip._x = 277;
questionClip._y = 205;
// 把题目编号输入MC的qNum文本框中
questionClip.qNum = currentQuestion + 1;
// questionsArray[currentQuestion]就是数组questionsArray里的第currentQuestion个对象,例如currentQuestion是0,那么就是我们的第一条题目
// questionsArray&#0;.questionText就是第一条题目对象的问题属性
// 然后问题输入MC的qText文本框中
questionClip.qText = questionsArray[currentQuestion].questionText;
// Create the individual answer clips in the question clip
// 以下循环将结合选项模版生成这一条题目的各个选项的MC
// questionsArray[currentQuestion].answers记得吗?选项这个属性可是个数组,所以我们把它的长度作为循环的次数,这个数组有多大,我们就生成多少个选项
for (var j = 0; j < questionsArray[currentQuestion].answers.length; j++) {

 


// Attach our linked answerTemplate clip from the Library.
// It contains a generalized button and a text field for the question.
// 用answerTemplate做模版生成MC,MC名为"answer" + j ,即第一个选项MC名为answer0,第二个为answer1,选项的名字可是关系到按钮选什么的,如果你忘了,看看上面有 @@ 标记的地方
// 同时它们的深度为j,每次不同
// 但和上面不同的是,我们要把选项MC生成到题目MC里,这样我们清除题目MC的同时也清除了选项
// 所以写成questionClip.attachMovie
questionClip.attachMovie("answerTemplate", "answer" + j, j);
// Place this answer clip in line below the question.
// 设定MC的位置,第一个高度为70,之后顺序加15
questionClip["answer" + j]._y += 70 + (j * 15);
questionClip["answer" + j]._x -= 100;
// Set the text field in the answer clip to the appropriate
// element of this question's answer array.
// 下面语句的:questionClip["answer" + j]可不是指数组,j=0的时候,它代表questionClip.answer0,具体解释可见上一章。


// 这句语句的作用是把questionsArray[currentQuestion]这个对象数组里面的answers[j]数组,输入到对应的选项MC的answerText文本框中,就是该选项的内容
questionClip["answer" + j].answerText = questionsArray[currentQuestion].answers[j];
}
//生成选项的循环结束
}
// Function to register the user's answers
// 以下是记录答题者答案的函数,记录在数组userAnswers中,和上一例同
// 每一个选项如果被选都会调用此函数,并用参数choice传来作答的答案
function answer (choice) {
userAnswers.push(choice);
// 判断是否题目全部完成,是的话清楚掉题目MC,并跳转到quizEnd帧
if (currentQuestion + 1 == questionsArray.length) {
questionClip.removeMovieClip();
gotoAndStop ("quizEnd");
} else {
// 在这里改变题目的编号,然后调用makeQuestion函数再次生成新的题目
currentQuestion++;
makeQuestion(currentQuestion);
}
}
// Function to tally the user's score
// 改题的函数
function gradeUser() {
// Count how many questions the user answered correctly


for (var j = 0; j < questionsArray.length; j++) {
// 将答题数组userAnswers[j]与问题数组questionsArray[j]的属性correctAnswer逐个比较
if (userAnswers[j] == questionsArray[j].correctAnswer) {
totalCorrect++;
}
}
// Show the user's score in an onscreen text field
// 显示答对与题目数比
displayTotal = totalCorrect + "/" + questionsArray.length;
}
好了,我们来总结一下这个例子吧
我们已经完成了第三个版本结束时候定下来目标,更快捷的建设,更便易的扩展
我们的题目跟选项都是动态生成的,也就是说生成10、100题或更多题目也只需要修改questionsArray.as这个文件就可以了
如果说生成两题这个例子用时要长于上面的例子,那么生成100题,你会发现用这个例子将是最快的。还有,在100题里面修改其中一题,也是最快的。
看完了例子,希望大家不是只明白了代码的含义,最重要是理解运用对象来编程的方法
同样的例子,其实还可以用其他的对象结构来完成的
更有效地组织数据也是编程艺术的一部分
为了更进一步改进我们的例子,最后一个,就是第五个版本,将用XML代替那个存放对象的数组(也就是在questionsArray.as里那个),它实在太难懂了,是不是啊?呵呵
XML,名字是不是很COOL啊,其实,FLASH里面用XML不难(其他地方的应用就……所以千万别说XML不难,是FLASH里面用不难),呵呵,好吧,开始吧。
[ 1 ]  [ 2 ]  [ 3 ]  [ 4 ]  

新闻标题 发布 时间
下雪效果,Flash初级入门教程 2007年11月15日 14:59:53
Photoshop入门教程:制作节日花纹特效字 2007年11月15日 14:00:51
Photoshop入门教程:轻松制作高质量WMP图标 2007年09月10日 17:38:12
Photoshop绘制像素画入门教程之三 2007年04月04日 17:34:48
Photoshop制作像素画入门教程之二 2007年04月04日 12:17:36
Photoshop制作像素入门教程之一 2007年04月03日 11:46:04
水鹰脚本系列——3DS MAX 脚本入门教程(1) 2006年09月15日 14:04:34
AS-入门教程 2005年04月02日 13:26:23
共有评论0条
更多评论..
作者信息 详细信息
评论人:
验证码:
内容:
 
about us advertisement publish conformity service cooperate associate link site map contact us help jump to the top of page