home | O'Reilly's CD bookshelfs | FreeBSD | Linux | Cisco | Cisco Exam    

Book HomeActionScript: The Definitive GuideSearch this book

13.10. The Last Quiz

Here's one final version of the multiple-choice quiz we started way back in Chapter 1, "A Gentle Introduction for Non-Programmers". This updated version of the quiz dynamically generates all of the quiz's questions and answers using movie clips, so our quiz is infinitely scalable and highly configurable. In fact, we're not far off from making the entire quiz a Smart Clip that could be customized by non-programmers.

The code for the quiz is shown in Example 13-5 and available from the online Code Depot. Because the quiz is now completely dynamically generated, 99% of the code fits entirely on one frame; we no longer need to fill a timeline with questions. (All we're missing is a preloader to ensure smooth playback over a network.) Note that we've used #include to import a block of code from an external text file. For more information on #include, see Part III, "Language Reference", and see Section 16.7, "Externalizing ActionScript Code" in Chapter 16, "ActionScript Authoring Environment". As an exercise, try adding new questions to the quiz by creating new objects and placing them in the questions array.

Though the code for the final quiz is relatively short, it's packed full of important techniques. With the exception of #include, we've seen all of them in isolation before, but this extended real-world example shows how they can all fit together. Study the comments carefully -- when you understand this version of the quiz in its entirety you'll be well-equipped to create advanced applications with ActionScript.

A longer explanation of the code in this quiz is available at:

http://www.moock.org/webdesign/lectures/ff2001sfWorkshop

Example 13-5. The Multiple-Choice Quiz, One Last Time

// CODE ON FRAME 1 OF THE MAIN TIMELINE
//  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
var userAnswers = new Array( );  // Array containing the user's guesses
var currentQuestion = 0;        // Number of the question the user is on

// Import the source file containing our array of question objects
// See explanation later in this example
#include "questionsArray.as"    

// Begin the quiz
makeQuestion(currentQuestion);

// The Question() constructor
function Question (correctAnswer, questionText, answers) {
  this.correctAnswer = correctAnswer;
  this.questionText = questionText;
  this.answers = answers;
}

// Function to render each question to the screen
function makeQuestion (currentQuestion) {
  // Clear the Stage of the last question
  questionClip.removeMovieClip( );

  // Create and place the main question clip
  attachMovie("questionTemplate", "questionClip", 0);
  questionClip._x = 277;
  questionClip._y = 205;
  questionClip.qNum = "question\n  " + (currentQuestion + 1);
  questionClip.qText = questionsArray[currentQuestion].questionText;

  // Create the individual answer clips in the question clip
  for (var i = 0; i < questionsArray[currentQuestion].answers.length; i++) {
    // Attach our linked answerTemplate clip from the Library;
    // It contains a generalized button and a text field for the question
    questionClip.attachMovie("answerTemplate", "answer" + i, i);
    // Place this answer clip in line below the question
    questionClip["answer" + i]._y += 70 + (i * 15);
    questionClip["answer" + i]._x -= 100;
    // Set the text field in the answer clip to the appropriate element of this
    // question's answer array
    questionClip["answer" + i].answerText =
        questionsArray[currentQuestion].answers[i];
  }
}

// Function to register the user's answers
function answer (choice) {
  userAnswers.push(choice);
  if (currentQuestion + 1 == questionsArray.length) {
    questionClip.removeMovieClip( );
    gotoAndStop ("quizEnd");
  } else {
    makeQuestion(++currentQuestion);
  }
}

// Function to tally the user's score
function gradeUser( ) {
  // Count how many questions the user answered correctly
  for (var i = 0; i < questionsArray.length; i++) {
    if (userAnswers[i] == questionsArray[i].correctAnswer) {
      totalCorrect++;
    }
  }
  // Show the user's score in an onscreen text field
  displayTotal = totalCorrect + "/" + questionsArray.length;
}

// CODE ON THE DYNAMICALLY GENERATED ANSWER BUTTONS
// Answer clips are generated dynamically and named in the series
// "answer0", "answer1",..."answern". Each answer clip contains a
// button that, when clicked, checks the name of the answer clip it's 
// in to determine the user's choice.
on (release) {
  // Trim the prefix "answer" off this clip's name
  choice = _name.slice(6, _name.length);
  _root.answer(choice);
}

// CODE ON THE quizEnd FRAME
gradeUser( );

The contents of the questionsArray.as file are as shown here:


// CODE IN THE questionsarray.as FILE
// -------------------------------------------------
// Contains an array of question objects that
// populate the questions and answers of a multiple-
// choice quiz. Compose new question objects according 
// to the following example.

/************** EXAMPLE QUESTION OBJECT ***************
  // Invoke the Question constructor with three arguments:
  //   a zero-relative number giving the correct answer, 
  //   a string giving the question text, and
  //   an array containing the multiple-choice answers
  new Question 
  (
    1,
    "question goes here?",
    ["answer 1", "answer 2", "answer 3"]
  )
*******************************************************/
// 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"])];


Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.











??????????????@Mail.ru