Advertisement
FastClick Ad Network
 

  

  

FLASH MX: CREATING A QUIZ APPLICATION USING XML

OVERVIEW

  
Suppose that we have these requirements for the quiz application:

  1. Be able to display a set of multiple choice quiz questions. 
  2. Each question can have 4 answers to choose from.  User can click one of the answers to select it.  A message will be displayed after each click, showing whether the selection is correct or not.
  3. A summary screen will be displayed at the end showing the percentage of the questions answered correctly.
  4. The Flash movie must be able to read the quiz data from a file. 
  5. The quiz data should be easily changed by an average user without rebuilding the Flash movie.  

Because of requirement 3 and 4, we will need a way to use one of Flash read file mechanism.  There are several to chose from, such as using getURL(), using XMLSocket, or loadVariables().  In this example, I will be utilizing the XML object for two reasons:

  • The structured organization of an XML file is better than the messy format of using text file (see here).
  • An XML file can be easily edited using a text editor.
  • XML is a mature standard, and you could potentially use the XML file for other purposes (such as displaying on a web page; or format the data to make a printout of the quiz).

To see how this might be done with a plain text file, see here

Warning: This tutorial and the application described here is mainly for informational and entertainment purpose.  The application should not be used for serious data collection or any other purpose which requires critical and accurate scoring.  The application does not attempt to create a secure environment; and someone can easily hack the application - including cracking the answers.   To illustrate the risk, consider this:
If you're running IE browser or later, y
ou can type the URLbelow into the browser and see the answer for all the items on the quiz:
http://www.permadi.com/tutorial/flashMXQuiz/quiz.xml
   

CREATING THE XML TEMPLATE

  
XML on itself is a rather complicated subject and I won't go into details.  There are certainly many books that covers this subject, from beginner to advanced.  For example: this or this (note: the link goes to a product page at at Amazon)   

If you have done some html, you might see some resemblances between the two.  Furthermore, once you see the sample XML file used on this tutorial, it will be quite obvious on how this particular XML data is structured.   I will also explain how to modify the data.

Here's the XML file used on this tutorial: quiz.xml (right click and select Save As to download it).  

This file can be opened using a text editor to edit and view.  You can also find some links to XML editors on the Related Products page. 

(Note: XML file is a plain-text file.  If you are using Wordpad or MSWord, you must save the file as a plain text file.)  A portion of the file is shown below (I only show 3 questions here, the file has about 11 questions):

<?xml version="1.0"?>
<!DOCTYPE quiz [
	<!ELEMENT quiz (title, items)>
	<!ELEMENT title (#PCDATA)>
	<!ELEMENT items (item)+>	
	<!ELEMENT item (question, answer, answer+)>
	<!ELEMENT question (#PCDATA)>
	<!ELEMENT answer (#PCDATA)>
	<!ATTLIST answer correct (y) #IMPLIED>
]>

<quiz>
  <title>The Quiz</title>
    <items>
      <item>
        <question>In which continent is the country Japan located?</question>
        <answer correct="y">Asia</answer>
        <answer>Europe</answer>
        <answer>Africa</answer>
        <answer>America</answer>
      </item>
      <item>
        <question>Which one cannot swim?</question>
        <answer>Tuna</answer>
        <answer correct="y">Cow</answer>
        <answer>Whale</answer>
        <answer>Lobster</answer>
      </item>		
      <item>
        <question>How many points are on a hexagon?</question>
        <answer>5</answer>
        <answer correct="y">6</answer>
        <answer>7</answer>
        <answer>8</answer>
      </item>		
    </items>
</quiz>
  • The root element is called <quiz>
  • A <quiz> has a <title> and a set of  <items>.  
  • <items> - plural - contains one or more <item> - singular.
  • An <item> consists of 1 <question> and 2 or more <answer>s.
  • <question> must come before <answer>s.
  • The correct answer is indicated by this attribute: correct="y".

Below is an example of an <item>.  (It starts with <item> tag and ends with </item> tag.)   

      <item>
        <question>A new question here.</question>
        <answer>An answer choice here.</answer>
        <answer>Another answer choice here also.</answer>
        <answer>Yet another answer choice here.</answer>
        <answer correct="y">This is the correct answer.</answer>
      </item>		

To add questions, just add/copy/replace an <item> element and change the content.  You can then change the question and the answers.  The correct answer should have the attribute: correct="y".  For example, above, the 4th answer is the correct answer.  There should be only one correct answer per <item>.

You might want to make sure that the questions (and the answers) are not too long, or they might not fit the Flash movie.  For now, you must put 4 answers per question.  Later, we will see how this can be changed.

You might not use the & or < within the question or answers.  If you need to use an &, type &amp; (note the "&" at the beginning and the ";" at the end and no space).  If you need to use <, type &lt; instead.

      <item>
        <question>Which number is &lt; than 3?</question>
        <answer correct="y">1 &amp; 2.</answer>
        <answer>5.</answer>
        <answer>8.</answer>
        <answer>777.</answer>
      </item>		

In that example above, the question will be displayed as: "Which number is < than 3?" but it must be written that way.  Similarly, the first answer will be displayed as: "1 & 2" by the XML processor.  Additionally, it's recommended to use the special notation for these symbols (these are also known as Name Entities) :

Symbol Name Entities
>
&gt;
" &quot;
' &apos;
& &amp;
< &lt;

You can also change the <title> element with any title you want to use.  For example, below, I added a new question at the end; replaced the 2nd question, and changed the title.

<?xml version="1.0"?>
<!DOCTYPE quiz [
	<!ELEMENT quiz (title, items)>
	<!ELEMENT title (#PCDATA)>
	<!ELEMENT items (item)+>	
	<!ELEMENT item (question, answer, answer+)>
	<!ELEMENT question (#PCDATA)>
	<!ELEMENT answer (#PCDATA)>
	<!ATTLIST answer correct (y) #IMPLIED>
]>

<quiz>
  <title>Sample Quiz (2/20/2002)</title>
    <items>
      <item>
        <question>In which continent is the country Japan located?</question>
        <answer correct="y">Asia</answer>
        <answer>Europe</answer>
        <answer>Africa</answer>
        <answer>America</answer>
      </item>
      <item>
        <question>Which one can fly?</question>
        <answer correct="y">A pigeon</answer>
        <answer>A rabbit</answer>
        <answer>A pig</answer>
        <answer>A lobster</answer>
      </item>		
      <item>
        <question>How many points are on a hexagon?</question>
        <answer>5</answer>
        <answer correct="y">6</answer>
        <answer>7</answer>
        <answer>8</answer>
      </item>		
      <item>
        <question>Which number is the largest?</question>
        <answer>2</answer>
        <answer>20</answer>
        <answer>200</answer>
        <answer correct="y">2000</answer>
      </item>		
    </items>
</quiz>

CREATING THE FLASH MOVIE


Open a new Flash movie and create the following layers configuration:

Put a  frame label called: "LoadData" on the frame 1 of Labels layer.  Then, put an image or something on the frame 1 of Bgr layer.  This will be the preloader screen.

  

LOADING THE QUIZ DATA
For this example, the quiz data file is called "quiz.xml," which you have seen above.   We will need to have Flash open the file and read the data.  Here's the code that reads the file.  This code needs to be put on the Actions layer, frame 1.

function QuizItem(question)
{
	this.question=question;
	this.answers=new Array();
        // reset statistic
	this.numOfAnswers=0;
	this.correctAnswer=0;

	// this function returns the question of this item
	this.getQuestion=function()
	{
		return this.question;
	}
	// add answer to multiple choice items     
	this.addAnswer=function(answer, isCorrectAnswer)
	{
		this.answers[this.numOfAnswers]=answer;
		if (isCorrectAnswer)
			this.correctAnswer=this.numOfAnswers;
		this.numOfAnswers++;
	}

	// this function returns the n-th answer
	this.getAnswer=function(answerNumberToGet)
	{
		return this.answers[answerNumberToGet];
	}
	
	// this function returns the index of the correct answer
	this.getCorrectAnswerNumber=function()
	{
		return this.correctAnswer;
	}

	// this function checks if the passed number is the
  	// correct answer index
	this.checkAnswerNumber=function(userAnswerNumber)
	{
		if (userAnswerNumber==this.getCorrectAnswerNumber())
			gotoAndPlay("Correct");
		else
			gotoAndPlay("Wrong");
	}
}

// this function parses the XML data into our data structure
function onQuizData(success)
{
	var quizNode=this.firstChild;
	var quizTitleNode=quizNode.firstChild;	
	title=quizTitleNode.firstChild.nodeValue;
	
	var i=0;
	// <items> follows <title>
	var itemsNode=quizNode.childNodes[1];
 	// go through every item and convert it into our data structure
	while (itemsNode.childNodes[i])
	{
		var itemNode=itemsNode.childNodes[i];
		// <item> consists of  <question> and one or 
                // more <answer>.
		// <question> always comes before <answer>s 
                // (Ie: <question> is the node 0 of <item>)
		var questionNode=itemNode.childNodes[0];
		quizItems[i]=new 
                        QuizItem(questionNode.firstChild.nodeValue);
		var a=1;
		// Go through every answer and add them
		// to our data structure.		
		// <answer> follows <question>
		var answerNode=itemNode.childNodes[a++];
		while (answerNode)
		{
			var isCorrectAnswer=false;
			if (answerNode.attributes.correct=="y")
				isCorrectAnswer=true;
			quizItems[i].addAnswer(
                                answerNode.firstChild.nodeValue, 
                                isCorrectAnswer);
			// goto the next <answer>
			answerNode=itemNode.childNodes[a++];
		}
		i++;
	}
	// We're done decoding, now we can start
	gotoAndStop("Start");
}
var myData=new XML();
myData.ignoreWhite=true;
myData.onLoad=onQuizData;
myData.load("quiz.xml");
stop();	 // I'm telling Flash not to continue until the XML is loaded.

The red section of code above opens the XML file and creates an XML object.  Flash will notify us when the file is completely loaded by calling a function called "onLoad".   At that time, we still need to parse the file or the data will not be usable.  We override the onLoad function with onQuizData.  This means that when the file is loaded, the onQuizData function will be called.  The stop() action at the ends tells Flash to stop running because I do not want to continue until the XML file is loaded.   So when does the code continues?  This will happen when the XML data is "completely" loaded.   

So, let's assume that the data is loaded.  We're now entering the onQuizData() function.  onQuizData() parses the data and creates a set of objects called quizItems.  After that, the line gotoAndStop("Start") will signal us that the XML file has been parsed.   

DATA STRUCTURE FOR THE QUIZ OBJECT
If you're not into programming, you might want to skip to CREATING THE QUIZ SCREEN below.   

Let's go back and examine the structure of the XML file above again.  An <item> contains 1 question, and 4 answers; one of the 4 answers will be correct.  It will be nice if we can reproduce the structure in the Flash application.  And that's what quizItems are.  Here are the properties of a quizItem.  

Notice several things:

  • question contains the question for the current item.  This represents the <question> element from the XML.
  • answers is an array that contains the set of answers.  This represent the <answer>s element from the XML file.
  • correctAnswer is the index of the correct answer.  The index starts at 0, so 0 in the above example means answers[0] ="Asia" is the correct answer.  The index represent the element with <answer correct="y"> in the XML.  
  • in addition, there are several functions that can be called by a quizItem:
    • addAnswer(answer): called by onQuizData to add answer as the XML data is being parsed.
    • checkAnswerNumber(userAnswerNumber): used when user clicks an answer.  You will see more of this later.
    • getAnswer(index): returns answers[index];

Since there are 11 questions in quiz.xml, there will be 11 quizItems.  Each one can be accessed like this: quizItems[index], where index is the question index (starting at 0).  Here' you can see the quizItem[0] being shown again.  You can compare it to the first <quiz> item in the XML file example, and see that they match.  

      <item>
        <question>In which continent is the country Japan located?</question>
        <answer correct="y">Asia</answer>
        <answer>Europe</answer>
        <answer>Africa</answer>
        <answer>America</answer>
      </item>

CREATING THE QUIZ SCREEN
Extends the timelines for all the layers to about 50 frames.  Then, create a key frame on the Label layer at around frame 10.  Put a  frame label: "Start."  On the Bgr layer, make another key frame at the same frame (at the frame labelled  "Start").  

Here, put a background image to be used when the quiz is running.  For example, I have this gray background, and I added the letter A, B, C, D on top of the background (you should try not to include the A, B, C, D in the background image itself):  

Make sure that there is enough space to put 2 or 3 lines of text for the question and answers.  Also, each answer choice should at least be able to accommodate long answers (spanning two lines).  

On the same frame of the QA Box layer, create 5 textboxes for the question and answers  like below (the blue boxes are textboxes):  These textboxes will contain the questions and answers when the application is running.

To be able to change the text during runtime, we must make sure that the textboxes are of type: "Dynamic Text."  Also, since a the text might not fit on a single line, make sure to select the "Multiline" option (see below).  You might also want to make the text left justified.  Also, select a common font such, otherwise some users might not have the font.

We need to associate the textbox with a variable name so that the textbox will display the text that we want.  For the Question placeholder textbox, I decided that I want the textbox to display a variable which I will call "question." so in Var: box, put "question" like below:

Make sure that this button is off so that user can't select (highlight) the text.  It will look weird if you allow user to select the text.  For the answer boxes, the settings are similar, except "Var: answer1" (see below).  

Do the same thing for the remaining 3 answer boxes.  Name then answer2, answer3, and answer4.

SHOWING THE QUIZ DATA ON THE QUIZ SCREEN

Now that we have the quiz screen laid out, let's put the questions into the screen.  Put this piece of code in the frame labeled "Start" frame of the "Actions" layer.

var currentQuestionNumber=1;
var numOfQuestionsAnsweredCorrectly=0;
var numOfQuestionsAnsweredIncorrectly=0;
gotoAndStop("ShowQuiz");

The currentQuizItems variable holds the currentQuizItem.  In the beginning, we set currentQuestionNumber to 1, indicating that we want to show the first quiz item.  Then we set 2 variables indicateing how many quations has been answered incorrectly and incorrectly (we'll use those to calculate the final score).  The next line tells Flash to go to another frame which is labeled "ShowQuiz."  We will be creating that frame now.

Then, on the Labels layer, at about frame 20, create a key frame named: ShowQuiz.  At this time, we need to extract the content of current quiz from the quizItems array that we created on the LoadData frame.   Put this piece of code in the frame labeled "Start" frame of the "Actions" layer.   

var currentQuizItem=quizItems[currentQuestionNumber-1];
var hasAnswered=false;
question=currentQuizItem.getQuestion();
for (var i=1; i<=4; i++)
{
  _root["answer"+i]=currentQuizItem.getAnswer(i-1);
}

stop();

The first line of the code assigns a variable currentQuizItem to the value of the current quiz item so that it's easy to refer to it in the future.  We can access the quiz items using  quizItems[index].   Since we have 10 quiz items, we have quizItems[0], quizItems[1], and so on, up to quizItems[9].  In the beginning, we want to start with the first quiz item, so we get the first quiz item by quizItems[currentQuestionNumber-1] (we set currentQuestionNumber to 1 on the previous section).

The line:

question=currentQuizItem.getQuestion();

extracts the <question> portion of the quiz and puts it to the variable question.   The code then loops through the answers and assigns the answers to variables answer1, answer2, answer3, and answer4.  Since we have named our textboxes with the same name as those variables (see CREATING THE QUIZ SCREEN above), when this piece of code is run, the textboxes will display the value of the variables, which is exactly what we wanted.  

Test the movie.  It should display the first quiz item like below:

Play around There is no interactivity at this point.  We still have to add the code for allowing the user to click the answer, and for checking the answer.  Make sure this part runs before continuing.
Download FLA
(this FLA contains the progress up to this section, continue to the next pages for subsequent versions)
Download XML (right click and do "Save As")

Try changing the first question on the XML file and see the changes being shown in the movie.

Note: This tutorial requires Flash 6/MX plug-in/player to be installed to run properly.  Although XML is supported from Flash 5; there's a problem on some older Flash 5 player that causes a movie not to be able to read some XML files correctly.  This problem occurred in Flash player version 5.0.41 and was fixed on version 5.0.42.  If the example above does not run on your machine, you should download the latest flash player from Macromedia.  If you need to support Flash 5 players, then see this document for some workarounds.

 

<<NEXT PAGE>>
<<
MORE TUTORIALS>>

Terms of Use

(C) 2002 F. Permadi
  

Advertisement