build a quiz in as3

21
Tutorial on building an interactive quiz in Flash Actionscript 3 flashbynight.com

Upload: em

Post on 15-Nov-2014

151 views

Category:

Documents


4 download

DESCRIPTION

This detailed tutorial shows you how to build a short quiz in flash AS3 from the ground up. This is a great project if you are starting out in flash and you want to learn in a hands-on way. Includes a section on reading data from xml or arrays. Suitable for e-learning specialists.

TRANSCRIPT

Page 1: Build a Quiz in AS3

Tutorial on building an

interactive quiz in Flash

Actionscript 3

flashbynight.com

Page 2: Build a Quiz in AS3

What you will learn:

• how to build a quiz using Flash AS3

• using randomization techniques

• storing data in arrays

• storing data in xml (optional)

Prerequisites:

• working copy of Flash version 8 or above

• working knowledge of how to use the Flash interface

* You can download the completed source files

from here: www.flashbynight.com/tutes/quiz.html

Making a quiz with randomized options in AS3

So here we go. We want to make a quiz in Flash AS3 where the options are randomized.

We may also want the questions to come up in a random order. What’s more, we may

want to reuse our code for further quizzes. How can we do all this? The answers are right

here in this tutorial. Read on.

Step 1

People have a funny habit of making tiny little Flash movies. But we want our quiz to be

big and exciting. Open up Flash and modify the stage size to 600 x 800. This way, we get

a nice big stage, but it will still display on laptop screens:

Page 3: Build a Quiz in AS3

Fine. Save the file under the name ‘quiz.fla’ and let’s move on.

Step 2

We need some sample questions for the purpose of the tutorial. We should have about

four, I think, so here they are:

Question 1: Where is Seoul?

Right Answer: South Korea

Wrong Answer: Japan

Wrong Answer: North Korea

Question 2: Where is Bucharest?

Right Answer: Romania

Wrong Answer: Hungary

Wrong Answer: Poland

Page 4: Build a Quiz in AS3

Question 3: Where is Copenhagen?

Right Answer: Denmark

Wrong Answer: Sweden

Wrong Answer: Finland

Question 4: Where is Lima?

Right Answer: Peru

Wrong Answer: Argentina

Wrong Answer: Chile

Now, we need to find a way to get the questions in a form that Flash can read. We will

look at two ways of doing this:

1 Storing the info in an array

2 Loading the questions from XML

The first option is the easiest, but the second option gives more flexibility. If you are a

beginner to AS3 or if you do not need to worry about reusing programming code, stick

to the array. Otherwise, check out how to use XML.

Now jump to step 4 if you want to get into the XML, otherwise proceed to step 3.

Step 3

A great way to store data is to put it in an array. In Flash, we can create an array like

this:

var names:Array=["Jon","Tony","Ralph"];

Then we can refer to the data as names[0], names[1], names[2]. Try it:

var names:Array=["Jon","Tony","Ralph"];

trace(names[2]);

Page 5: Build a Quiz in AS3

The program should output Ralph.

By the way, we are going to put all our code on the main timeline for this tutorial. This is

not considered cool by advanced programmers, who like to stick everything in external

.as files, but we’re going to do it anyway.

So on the main timeline, and in the first frame, add the following to a layer named

data:

var questions:Array=["Where is Seoul? ","Where is Bucharest? ","Where is Copenhagen?

","Where is Lima? "];

That’s our array done to hold our questions. Now for the answer options, we will use a

slightly more advanced technique: an array of arrays. That means we will hold our three

options for each question in an array like so:

["South Korea","Japan","North Korea"]

And we will store all these arrays as a ‘master array’, like so:

var answers:Array=[ ["South Korea","Japan","North Korea"],

["Romania","Hungary","Poland"], ["Denmark","Sweden","Finland"] ,[

"Peru","Argentina","Chile"] ];

Now we can access our questions in the following way: The correct answer for question

2 is answers[1][0]. The dummy answers are answers[1][1] and answers[1][2]

Question 2 is referenced by answers[1] because the first entry in an array is identified as

0, not 1. Try the following traces:

trace(questions[1]);

trace(answers[1]);

trace(answers[1][0]);

trace(answers[1][1]);

trace(answers[1][2]);

Page 6: Build a Quiz in AS3

Now that we have stored our question data, move on to Step 4 to see how we could

do this using XML or move on to Step 5 to set up the interface.

Step 4

In Step 3, we learned how to store our questions and answers in an array. Now we will

load the questions and answers in from an external XML file and store them in the same

arrays.

First, we need an XML file, obviously. You don’t need any special software for this; you

can simple write the XML into a wordpad document or text document and then

change the file extension to XML.

So open a word pad document and type out the following:

<all>

<ques>

<q1>Where is Seoul?</q1>

<op1>South Korea</op1>

<op2>North Korea</op2>

<op3>Japan</op3>

</ques>

<ques>

<q1>Where is Bucharest?</q1>

<op1>Romania</op1>

<op2>Hungary</op2>

<op3>Poland</op3>

</ques>

<ques>

<q1>Where is Copenhagen?</q1>

<op1>Denmark</op1>

<op2>Sweden</op2>

<op3>Finland</op3>

</ques>

<ques>

<q1>Where is Lima?</q1>

<op1>Peru</op1>

<op2>Argentina</op2>

<op3>Chile</op3>

</ques>

</all>

Now save this as sample.xml. The beauty of XML is that it can be read easily by various

programs running in flash, php, javascript and so on, but it can also be read by humans.

For example, looking above, it is easy to see that the label <ques> refers to a question

Page 7: Build a Quiz in AS3

and <op1> refers to the first option, which we will use to store the answer. These labels

are called nodes.

Let’s load the data into Flash. To do this, we need a few lines of code:

var loader:URLLoader = new URLLoader();

loader.addEventListener(Event.COMPLETE, loadXML);

loader.load(new URLRequest("sample.xml"));

function loadXML(e:Event):void

{

var myxml = new XML(e.target.data);

trace(myxml);

}

The above code first creates a URLLoader, then adds a ‘listener’ that checks when the

loader has completed its job. The third line requests that the loader gets data from our

file, sample.xml. The fourth line begins a function that will run when the data is loaded

(as called from line 2). Inside this function, we declare a variable to hold the info and

then run a trace to check it is working. Once you are sure it is working, you can remove

the trace.

What is happening now is that we have the data loaded into our flash movie and we

want to manipulate it so that we can stick it into an array. Let’s do it.

We need to define two empty arrays, one to hold the questions and one to hold the

answer options:

var questions:Array=new Array();

var answers:Array=new Array();

Put this code before the previous code.

Next, we need a way to populate the arrays with the data. Replace the line

trace(myxml); with the following:

var loop =myxml.ques.length();

for (var i=0;i<loop;i++){questions[i]=myxml.ques[i].q1;

answers[i]=[myxml.ques[i].op1,myxml.ques[i].op2,myxml.ques[i].op3];

}//loop

gotoAndPlay(2);

Page 8: Build a Quiz in AS3

Okay, some explanation is necessary. We want to run a loop as many times as we have

questions in our XML document. We can find out how many questions there are with

myxml.ques.length and we set a variable loop equal to this.

As flash loops, the value i will increase. We want questions[0] to be the first question

from the xml and questions[1] to be the second one and so on. We can do this using

questions[i]=myxml.ques[i].q1; You can notice that we read the data in an xml node in

a similar way to how we read an array.

We want our answers array to be a multidimensional array (see step 3). So we use this

line:

answers[i]=[myxml.ques[i].op1,myxml.ques[i].op2,myxml.ques[i].op3];

Hence, answers[1] = [Romania, Hungary, Poland];

If this seems confusing, try tracing the data and you will get the hang of it soon enough.

The last line takes us to frame 2, now that the data is all loaded and our quiz is ready to

go.

Let’s double-check your code is all correct:

var questions:Array=new Array();

var answers:Array=new Array();

var loader:URLLoader = new URLLoader();

loader.addEventListener(Event.COMPLETE, loadXML);

loader.load(new URLRequest("sample.xml"));

function loadXML(e:Event):void

{

var myxml = new XML(e.target.data);

var loop =myxml.ques.length();

for (var i=0;i<loop;i++){questions[i]=myxml.ques[i].q1;

answers[i]=[myxml.ques[i].op1,myxml.ques[i].op2,myxml.ques[i].op3];

}

gotoAndPlay(2);

}

stop();

Page 9: Build a Quiz in AS3

Step 5

Add another layer to the timeline and name it Questions. Make sure the questions layer

is below the data layer. We’ll place the rest of our code here.

If you are loading the data via xml, put this layer on the second frame:

(We wish to make sure the xml is loaded before displaying the questions, or we will have

a nasty ‘undefined’ message and other errors. The quick and dirty way of doing this is

putting the questions on the next frame. )

We need to display our questions, so let’s add some dynamic text fields to the stage.

Here’s how I did mine:

Page 10: Build a Quiz in AS3

I labeled the text in the first box as simply q, and the text in the other boxes as opt1,

opt2 and opt3:

The y-position of the boxes will be important later on (so we know where to position the

ticks and crosses). It is also important for aesthetics for the boxes to be evenly spaced.

My text boxes (for the answer options) are at 160, 260 and 360:

Now, before we look at displaying the questions and answers randomly, let’s do a

version where we cycle through the questions in the order they are in the database. We

will need the following code:

var qno=0;

function change_question(){

q.text=questions[qno];

opt1.text=answers[qno][0];

opt2.text=answers[qno][1];

opt3.text=answers[qno][2];

}//function change_question

change_question();

Page 11: Build a Quiz in AS3

This code basically sets the current question number and sets the text boxes according

to the data in our arrays in a function named change_question. When you play the

Flash movie, you should see this:

Obviously this is no good because the first option is always going to be correct. We

need to mix it up a bit. Let’s randomize the questions. We need to change the code in

our function to this:

var qno=0; var rnd1;

function change_question(){

rnd1=Math.ceil(Math.random()*3);

q.text=questions[qno];

if(rnd1==1){opt1.text=answers[qno][0];opt2.text=answers[qno][1];opt3.text=answ

ers[qno][2];}

if(rnd1==2){opt1.text=answers[qno][2];opt2.text=answers[qno][0];opt3.text=answ

ers[qno][1];}

if(rnd1==3){opt1.text=answers[qno][1];opt2.text=answers[qno][2];opt3.text=answ

ers[qno][0];} }//function change_question

Page 12: Build a Quiz in AS3

change_question();

We declare a new variable called rnd1. Then we assign a random number between

one and three to rnd1 using the line: rnd1=Math.ceil(Math.random()*3);

The way it works is this: Math.random()returns a number at random between 0 and 1.

Math.random()*3 gives us a random number between 0 and 3. We use Math.ceil to

round our number up so that we get a whole number. To cut a long story short, if you

want a random number out of 10, replace the 3 with a 10 and so on.

We use our random number to generate one of three different answer patterns. Now

the correct answer could be option 1, option 2 or option 3. Run the movie a few times

to observe that the options are different each time.

Step 6

We need a button to change the questions for us. Draw a button on the stage below

the text boxes. Right-click on it and choose convert to symbol, then choose button as

the symbol type. Here is mine:

Give the instance on the stage the name ‘next_b’.

Now we need to add a ‘listener’ to listen for when the button is clicked and we need a

function to run when the button is clicked. Here is how we do that:

Adding a listener:

next_b.addEventListener(MouseEvent.CLICK, ButtonAction1);

Defining the function ButtonAction1:

function ButtonAction1(eventObject:MouseEvent) {qno++;change_question();}

Page 13: Build a Quiz in AS3

These two lines of code should come after the previous code. qno++ increases the

variable qno by one and then we run the function change_question(). You should see

that as you press the NEXT button, we cycle through the four questions.

Up until now, we have only been displaying the questions. We need to give the user the

option to click on the answers and receive feedback on whether the choice is correct

or not. Let’s do that in Step 7:

Step 7

Draw a blue box directly on top of each dynamic text box and convert each one to a

movie clip (make sure you don’t select the text box by accident). Give them the names

shade1, shade2 and shade 3. Here is what I have now:

Page 14: Build a Quiz in AS3

Change the alpha value of each one to 14%. This makes each movie clip mostly

transparent.

Now we need to add a piece of code that basically says, ‘If you click on option 1 and

the answer is 1, display a tick. Otherwise display a cross. Oops! We need to draw a tick

and a cross first. Here are mine:

For the moment, the y-position is not important, but you should position them where you

want them to appear on the screen in regard to the x-position. Just beside the options

should be fine. Make sure the cross has the instance name ‘cross’ and the tick has the

instance name ‘tick’.

We need to make the tick and cross invisible until you click on an option. So after the

line where we declare our variables (that’s line 2), add:

tick.visible=false;cross.visible=false;

We need to detect when an option is clicked, which means more listeners, of course:

shade1.addEventListener(MouseEvent.CLICK, ButtonAction2);

shade2.addEventListener(MouseEvent.CLICK, ButtonAction3);

shade3.addEventListener(MouseEvent.CLICK, ButtonAction4);

Page 15: Build a Quiz in AS3

Now we need to perform a check when an option is clicked: is it the correct answer or

not. We know from our previous code that if rnd1==1, option 1 is the correct answer; if

rnd1==2, option 2 is the correct answer. We can use this when we check the answers:

function ButtonAction2(eventObject:MouseEvent)

{if(rnd1==1){tick.visible=true;tick.y=shade1.y}else{cross.visible=true;cross.y=shade1.y}}

function ButtonAction3(eventObject:MouseEvent)

{if(rnd1==2){tick.visible=true;tick.y=shade2.y}else{cross.visible=true;cross.y=shade2.y}}

function ButtonAction4(eventObject:MouseEvent)

{if(rnd1==3){tick.visible=true;tick.y=shade3.y}else{cross.visible=true;cross.y=shade3.y}}

So we have told Flash to display a tick (by making it visible) if the right answer has been

selected and to display a cross if the wrong answer has been selected. We have also

positioned the tick/cross next to the option that was clicked.

Now we have some refinements to make. In our change_question() function, we need

to reset the tick and cross to invisible before the next answer is chosen. We add this

code to the first line of the function:

tick.visible=false;cross.visible=false;

In fact, now we don’t need the code on line 2, because it is repetitive.

The next refinement is that we want the options to ‘lock up’ after the user has chosen

an answer. We can use the property ‘mouse.Enabled’ to do this. Let’s write a short

function:

function enable_disable(a){

if(a==0){shade1.mouseEnabled=false;shade2.mouseEnabled=false;shade3.mouseEnabl

ed=false;}

if(a==1){shade1.mouseEnabled=true;shade2.mouseEnabled=true;shade3.mouseEnable

d=true;}}

So as we can see, if we call enable_disable(0), it will lock the options and if we call

enable_disable(1), it will disable the options. We want to lock the options after an

answer has been chosen and unlock the options when we change the question.

Here is all the code so far in the questions layer:

Page 16: Build a Quiz in AS3

var qno=0;var rnd1;

tick.visible=false;cross.visible=false;

function change_question(){tick.visible=false;cross.visible=false;

rnd1=Math.ceil(Math.random()*3);

q.text=questions[qno];

enable_disable(1);

if(rnd1==1){opt1.text=answers[qno][0];opt2.text=answers[qno][1];opt3.text=answ

ers[qno][2];}

if(rnd1==2){opt1.text=answers[qno][2];opt2.text=answers[qno][0];opt3.text=answ

ers[qno][1];}

if(rnd1==3){opt1.text=answers[qno][1];opt2.text=answers[qno][2];opt3.text=answ

ers[qno][0];}

}

function enable_disable(a){

if(a==0){shade1.mouseEnabled=false;shade2.mouseEnabled=false;shade3.mous

eEnabled=false;}

if(a==1){shade1.mouseEnabled=true;shade2.mouseEnabled=true;shade3.mouse

Enabled=true;}}

change_question();

next_b.addEventListener(MouseEvent.CLICK, ButtonAction1);

function ButtonAction1(eventObject:MouseEvent) {qno++;change_question();}

shade1.addEventListener(MouseEvent.CLICK, ButtonAction2);

shade2.addEventListener(MouseEvent.CLICK, ButtonAction3);

shade3.addEventListener(MouseEvent.CLICK, ButtonAction4);

function ButtonAction2(eventObject:MouseEvent)

{enable_disable(0);if(rnd1==1){tick.visible=true;tick.y=shade1.y}else{cross.visible=true;cro

ss.y=shade1.y}}

function ButtonAction3(eventObject:MouseEvent)

{enable_disable(0);if(rnd1==2){tick.visible=true;tick.y=shade2.y}else{cross.visible=true;cro

ss.y=shade2.y}}

function ButtonAction4(eventObject:MouseEvent)

{enable_disable(0);if(rnd1==3){tick.visible=true;tick.y=shade3.y}else{cross.visible=true;cro

ss.y=shade3.y}}

Page 17: Build a Quiz in AS3

So far we have the ability to display the questions with the options randomized,

navigate to the next question and check if the answer is right or wrong. The next step is

to track the correct and incorrect answers and to display the score at the end of the

quiz.

Step 8

To track the number of right and wrong answers, we’ll need more variables, so on line 3,

add the following:

var right_answers=0;var wrong_answers=0;

And we have to amend a few lines to count the right and wrong answers. A quick and

dirty way to do this is at the beginning of the change_question function. If the tick is

visible, we know a right answer has been chosen. If a cross is visible, a wrong answer

has been chosen:

if(tick.visible){right_answers++;}

if(cross.visible){wrong_answers++;}

This code is short form for something like this:

if(tick.visible==true){right_answers=right_answers+1;}

We will know when all the questions have been completed because the question

number (qno) will be equal to the length of the array that holds the questions. What do

we want to do when we reach the last question? We’ll go to an outro page that we will

put on frame 2. So after the two lines of code we just added, let’s add another line:

function change_question(){

if(tick.visible){right_answers++;}

if(cross.visible){wrong_answers++;}

if(qno==questions.length){gotoAndPlay(2);}else{

tick.visible=false;cross.visible=false;

rnd1=Math.ceil(Math.random()*3);

q.text=questions[qno];

enable_disable(1);

if(rnd1==1){opt1.text=answers[qno][0];opt2.text=answers[qno][1];opt3.text=answ

ers[qno][2];}

Page 18: Build a Quiz in AS3

if(rnd1==2){opt1.text=answers[qno][2];opt2.text=answers[qno][0];opt3.text=answ

ers[qno][1];}

if(rnd1==3){opt1.text=answers[qno][1];opt2.text=answers[qno][2];opt3.text=answ

ers[qno][0];}

}}

Note the ELSE statement and the extra curly bracket on the last line. We are telling Flash

to go to frame 2 if the questions are finished. Otherwise, continue as normal.

*If you are loading the data from xml, you need to replace gotoAndPlay(2); with

gotoAndPlay(3);

Add a stop(); to frame 1, then insert a new frame and also add a stop(); Without the

stop();, the movie will run on a constant loop.

On frame 2 (frame 3 if you’re using xml), add the following:

The two dynamic text boxes have instance names ra and wa respectively. We can add

the following code to control their display:

ra.text=right_answers;

wa.text=wrong_answers;

Page 19: Build a Quiz in AS3

Well, it looks like we’ve almost finished. I promised I would show how to randomize the

order of the questions. Let’s do that in Step 9 and then we’re done.

Step 9

We wish to display the questions in a random order. There are many ways to do this, but

I’ll show you a quick and dirty method that works a treat.

Declare a variable rnd2 in line one, then add the underlined code to our

change_questions() function:

function change_question(){

if(tick.visible){right_answers++;}

if(cross.visible){wrong_answers++;}

if(qno==questions.length){gotoAndPlay(2);}else{

tick.visible=false;cross.visible=false;

rnd1=Math.ceil(Math.random()*3);

rnd2=Math.ceil(Math.random()*questions.length)-1;

q.text=questions[rnd2];

if(questions[rnd2]=="x"){change_question();}

questions[rnd2]="x";

enable_disable(1);

if(rnd1==1){opt1.text=answers[rnd2][0];opt2.text=answers[rnd2][1];opt3.text=answ

ers[rnd2][2];}

if(rnd1==2){opt1.text=answers[rnd2][2];opt2.text=answers[rnd2][0];opt3.text=answ

ers[rnd2][1];}

if(rnd1==3){opt1.text=answers[rnd2][1];opt2.text=answers[rnd2][2];opt3.text=answ

ers[rnd2][0];}

}}

We have four new lines of code:

rnd2=Math.ceil(Math.random()*questions.length)-1;

This chooses a random number of the length of the array that holds our questions. (But

minus 1, because we count the elements in an array from 0.)

q.text=questions[rnd2];

We use our random number to choose a question at random.

Page 20: Build a Quiz in AS3

questions[rnd2]="x";

Once the question is chosen and displayed, we change the data in the array to “x”, so

that we have a way to know which questions have already been displayed. Changing

the data to “x” is a lot less bother than removing the element from the array for reasons

I won’t go into here.

if(questions[rnd2]=="x"){change_question();}

If we choose a question that has already been “x”ed, we simply run the

change_questions() function again. When we call a function from within itself, this is

called a ‘recursive’ function. This little technique saves us lines and lines of code.

Our quiz is ready! Check it out and make sure that it works. The full code for the

questions frame is listed below. Remember that you can also download the .fla files

from www.flashbynight.com/tutes/quiz.html

var qno=0;var rnd1; var rnd2;

tick.visible=false;cross.visible=false;

var right_answers=0;var wrong_answers=0;

function change_question(){

if(tick.visible){right_answers++;}

if(cross.visible){wrong_answers++;}

if(qno==questions.length){gotoAndPlay(2);}else{

tick.visible=false;cross.visible=false;

rnd1=Math.ceil(Math.random()*3);

rnd2=Math.ceil(Math.random()*questions.length)-1;

q.text=questions[rnd2];

if(questions[rnd2]=="x"){change_question();}

questions[rnd2]="x";

enable_disable(1);

if(rnd1==1){opt1.text=answers[rnd2][0];opt2.text=answers[rnd2][1];opt3.text=answ

ers[rnd2][2];}

if(rnd1==2){opt1.text=answers[rnd2][2];opt2.text=answers[rnd2][0];opt3.text=answ

ers[rnd2][1];}

if(rnd1==3){opt1.text=answers[rnd2][1];opt2.text=answers[rnd2][2];opt3.text=answ

ers[rnd2][0];}

}}

Page 21: Build a Quiz in AS3

function enable_disable(a){

if(a==0){shade1.mouseEnabled=false;shade2.mouseEnabled=false;shade3.mous

eEnabled=false;}

if(a==1){shade1.mouseEnabled=true;shade2.mouseEnabled=true;shade3.mouse

Enabled=true;}}

change_question();

next_b.addEventListener(MouseEvent.CLICK, ButtonAction1);

function ButtonAction1(eventObject:MouseEvent) {qno++;change_question();}

shade1.addEventListener(MouseEvent.CLICK, ButtonAction2);

shade2.addEventListener(MouseEvent.CLICK, ButtonAction3);

shade3.addEventListener(MouseEvent.CLICK, ButtonAction4);

function ButtonAction2(eventObject:MouseEvent)

{enable_disable(0);if(rnd1==1){tick.visible=true;tick.y=shade1.y}else{cross.visible=true;cro

ss.y=shade1.y}}

function ButtonAction3(eventObject:MouseEvent)

{enable_disable(0);if(rnd1==2){tick.visible=true;tick.y=shade2.y}else{cross.visible=true;cro

ss.y=shade2.y}}

function ButtonAction4(eventObject:MouseEvent)

{enable_disable(0);if(rnd1==3){tick.visible=true;tick.y=shade3.y}else{cross.visible=true;cro

ss.y=shade3.y}}

stop();