13.10. The Last QuizHere'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: 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"])]; Copyright © 2002 O'Reilly & Associates. All rights reserved. |
|