AS基础教程整理第11/13页

 更新时间:2007年03月22日 00:00:00   作者:  

第十二章 第四个版本的选择题

第三个版本的时候我们已经设想好,新版本中题目将是动态生成的,不用我们在FLASH的场景里面一题一题输入了,我们要做的只是输入题目和题目答案的数据就够了。
很明显,每一条题目都将是一个对象(不然我们学这么多对象的知识干嘛?),而这些所有的题目,会用一个数组来存放

再重提一下,可配合源程序学习 http://www.moock.org/webdesign/l ... op/moockQuizzes.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 ActionScript formally declared a scripting language?",
     ["version 3", "version 4", "version 5"]),

   new Question (1,
     "Are regular expressions supported by Flash 5 ActionScript?",
     ["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,
     "Actionscript is based on...",
     ["Java", "JavaScript", "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里那个),它实在太难懂了,是不是啊?呵呵

相关文章

最新评论