Advertisement
FastClick Ad Network

  

  

FLASH MX: CREATING ONLINE QUIZ APPLICATION USING XML

  
ADDING SUPPORT FOR QUESTIONS WITH DIFFERENT NUMBER OF ANSWER CHOICES

Casale Media - the world's fastest growing online advertising network!

So far, all the questions in the quiz contains four answer to choose from.  Let's extend the functionality so that we can support a question with only two answers to choose from, such as in true/false questions.  Once you understand how this works, you can add support for 3, 5, or more choices.

First, I'll modify the first quiz item so that there are only 2 answers to chose from:

<?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>10 is &gt; -10.</question>
	<answer correct="y">True</answer>
	<answer>False</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>6</answer>
        <answer>7</answer>
        <answer correct="y">8</answer>
      </item>		
    </items>
</quiz>

Here's the XML file: quiztf.xml

The bold portion is the changes that I made.  Notice that the &gt; is an entity name (see first part of tutorial if you're not sure that means and why we need it).   So, the question will be translated to: 10 is > than -10.; and the user will have two answers to choose from: True or False.  

Now, we need to modify the Flash side.  Go back to the Action layer, first frame.   We just need to add one function for QuizItem object.  The function will return the number of answers, and it's called: getNumOfAnswers().  The changes are in bold below:

function QuizItem(question)
{
	this.question=question;
	this.answers=new Array();
	this.numOfAnswers=0;
	this.correctAnswer=0;
	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.getAnswer=function(answerNumberToGet)
	{
		return this.answers[answerNumberToGet];
	}
	
	this.getCorrectAnswerNumber=function()
	{
		return this.correctAnswer;
	}
	
	this.checkAnswerNumber=function(userAnswerNumber)
	{
		if (userAnswerNumber==this.getCorrectAnswerNumber())
			gotoAndPlay("Correct");
		else
			gotoAndPlay("Wrong");
	}
 	this.getNumOfAnswers=function()
	{
		return this.answers.length;	
	}
}

Keep the remaining code intact (except, make sure that the XML file is the new file: quiztf.xml if you're using the new XML file).  If you run the movie now, it should show this:

Now, you can still click the third and fourth answers.  That's not good, we need to make it so that:

1) only valid answers are shown
2) disable the buttons for unused answers

To do 1), we need to convert the those A, B, C, D letters on the screen to symbols, so that we can hide them when necessary.  Let's do the A:

Hide the Buttons layer first.  Select the A shape (or text - depending on how you made the letter), then Convert to Symbol.  Name it A.

Then, select the symbol on the stage, go to its property panel, and assign an instance name to it.  Below, I name it: "answer1Mark".


(Make sure not to put  <SPACE> accidentally at the end and at the beginning of the  name.)

Do the same for B, C, and D.  
For B, name the instance "answer2Mark"
For C, name the instance "answer3Mark"
For D, name the instance "answer4Mark"

Now that we have named those instances (let's call them "answer marks") we can hide them by editing the code in the Actions layer on the ShowQuiz frame:

if (currentQuestionNumber>quizItems.length)
	gotoAndStop("SummaryScreen");

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

for (; i<=4; i++)
{
	_root["answer"+i+"Mark"]._visible=false;
}
stop();

The line 

currentQuizItem.getNumOfAnswers() 

tells Flash to only add as many answers as specified on the XML. 

We then turn off the answer marks by this loop:

for (; i<=4; i++)
{
	_root["answer"+i+"Mark"]._visible=false;
}

Within that loop, this portion of the code:

_root["answer"+i+"Mark"]._visible=false; 

hides the unused answer marks.  

But wait, we need to make sure that those marks are visible again for the next questions, and that's what this does:

_root["answer"+i+"Mark"]._visible=true; 

Now, test the movie with the new XML.  It will show this:
(Note: if for some reasons the code doesn't work, make sure there's no  <SPACE> at the end or the beginning of the instance name.)

The answer marks are gone, but notice that we need to also hide the answer textboxes.  We can do that with the same technique:

Go to the property panel of the answer textboxes and name them in this order from top to bottom: answer1Textbox, answer2Textbox, answer3Textbox, answer4Textbox.

And to hide/show them, add the following code (in bold)

if (currentQuestionNumber>quizItems.length)
	gotoAndStop("SummaryScreen");

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

for (; i<=4; i++)
{
	_root["answer"+i+"Mark"]._visible=false;
	_root["answer"+i+"Textbox"]._visible=false; 
}
stop();

Run it now.  It should be like this:

That looks good, but if you click your mouse around the area where the third and the fourth answers are used to be, you can still click those non-existent answers.  We need to hide those unused buttons.  Again, we do the same as before: name the button instances, then hide/unhide them.

Go to each button's property panel, then name them in this order from top to bottom: answer1Button, answer2Button, answer3Button, answer4Button.

And to hide/show them, add the following code (in bold)

if (currentQuestionNumber>quizItems.length)
	gotoAndStop("SummaryScreen");

var currentQuizItem=quizItems[currentQuestionNumber-1];
var hasAnswered=false;
question=currentQuizItem.getQuestion();
for (var i=1; i<=currentQuizItem.getNumOfAnswers(); i++)
{
	_root["answer"+i]=currentQuizItem.getAnswer(i-1);
	_root["answer"+i+"Mark"]._visible=true; 
	_root["answer"+i+"Textbox"]._visible=true; 
	_root["answer"+i+"Button"]._visible=true; 
}

for (; i<=4; i++)
{
	_root["answer"+i+"Mark"]._visible=false;
	_root["answer"+i+"Textbox"]._visible=false; 
	_root["answer"+i+"Button"]._visible=false; 
}
stop();

If you want to support more than 4 answer choices, change the number 4 on the second loop above to the number of answer choices you desire.  (You must create the textboxes and the other elements for them.)

  

<<MORE IMPROVEMENTS>>
<<MORE TUTORIALS>>

(C) 2002 F. Permadi
 
Terms of Use