Advertisement

Create a Customizable Flash Quiz Application

by

We’re going to design a clean interface, created with the Flash Tools, which we’ll use along with ActionScript and XML to develop a Quiz application capable of loading images, text and sounds.


Step 1: Brief Overview

A clean interface created with the Flash Tools will be used along with ActionScript and XML to develop a Quiz application capable of loading images, text and sounds.


Step 2: Flash Document Settings

Open Flash and create a 480 pixels wide, 320 pixels tall document. Set the Frame rate to 24fps.



Step 3: Interface


The interface consists of simple graphics, MovieClips and TextFields. We'll look at how it was made in the following steps.


Step 4: Background


Select the Rectangle Primitive Tool (R) and create a #D9E6EF - #F6F9FF, 450x290px rectangle, change the corner radius to 12 and convert it to a MovieClip. Use the following filter to get the inner look:



Step 5: Title

 

Use a font that you like to create the application title, you can also add an icon to make it look even better. I opted for Aller Bold, freely available from FontSquirrel.com.


Step 6: Buttons


Using the same tool as for the background, create two 80x24px rectangles and fill them with #0086C6. Use the Text Tool (T) to add a label to them and convert them to Buttons. Set their instance names to playB and creditsB.

This will complete the Menu Screen; convert the elements in stage to a single MovieClip and name it menuScreen.


Step 7: Question Panel


Here we start building the Game Screen.

Reuse the background and title created in the previous steps and use the Rectangle Primitive Tool to create a 360x48px rectangle. Add a Dynamic TextField with the Text Tool and name it questionTF. Convert both to MovieClip and name it qPanel.


Step 8: Answer Panel


Repeat the process used before with four 140x38px rectangles, name them button1 to button4 and convert them all to a single MovieClip named aPanel. Name the text fields within the buttons oneTF, twoTF, threeTF, and fourTF, respectively.


Step 9: Credits Screen

The Credits Screen will show the year and copyright of the game.

It will be pretty simple to create as we already have all the elements used in it.


Convert the graphics to a MovieClip and name it CreditsScreen, remember to mark the Export for ActionScript box.


Step 10: Game Over

This screen will appear when the quiz is finished, it shows the final score percentage and the questions you answered right or wrong.


Use the Text Tool to add three Dynamic TextFields and name them scoreTF, caTF, and waTF. Convert the graphics to a MovieClip and name it GameOver, remember to mark the Export for ActionScript box.


Step 11: Tween Nano


We'll use a different tween engine from the default included in Flash, this increases performance as well as being easier to use.

You can download Tween Nano from its official website. See this guide to learn how to add the engine to your project.


Step 12: Soungle


We'll include the ability to add sound to the quiz; you can find the sound used in this example at Soungle.com using the keyword phone ring.


Step 13: XML

An XML file will be used to get all the quiz data, this includes questions, possible answers, correct anwers, images and sounds. Open your favorite XML editor and write the following code:

 
<?xml version="1.0"?> 
  <questions> 
   
  <question option1='Monkeys!' option2='Costumes' option3='Computers' answer="Flash Files" image='' sound=''>What does Activeden sell?</question> 
  <question option1='Club of 8s' option2='8 of Plant' option3='8 of Spades' answer="Eight of Clubs" image='c8.png' sound=''>What is the name of this Card?</question> 
  <question option1='Guitar' option2='Koala Bear' option3='Alarm Clock' answer="Phone Ring" image='' sound='Phone.mp3'>What is this sound?</question> 
 
</questions>

As you can read in the code, it is really easy to spot which part does what so there shouldn't be any problem here. Remember that we will build the engine to interpret this file, this means you can add/edit/remove any questions here as long as you follow this basic structure.


Step 14: Create a new ActionScript Class


Create a new (Cmd + N) ActionScript 3.0 Class and save it as Main.as in your class folder.


Step 15: Class Structure

Create your basic class structure to begin writing your code.

 
package  
{ 
	import flash.display.Sprite; 
	 
	public class Main extends Sprite 
	{ 
		public function Main():void 
		{ 
			// constructor code 
		} 
	} 
}

Step 16: Required Classes

These are the classes we'll need to import for our class to work; the import directive makes externally defined classes and packages available to your code.

 
import flash.display.Sprite; 
import flash.net.URLLoader; 
import flash.net.URLRequest; 
import flash.events.MouseEvent; 
import com.greensock.TweenNano; 
import com.greensock.easing.Elastic; 
import flash.events.Event; 
import flash.net.navigateToURL; 
import flash.display.Loader; 
import flash.media.Sound;

Step 17: Variables

These are the variables we'll use, read the comments in the code to find out more about them, some of their names are self explanatory so there will be no comment there.

 
private var credits:CreditsScreen; 
private var xmlLoader:URLLoader; 
private var xml:XML; 
private var nextQ:int = 0; //stores the next question number 
private var imgLoader:Loader; 
private var sndLoader:Sound; 
private var answer:String;//stores the correct answer 
private var ca:int = 0;//counts the correct answers 
private var wa:int = 0;//counts the wrong answers

Step 18: Constructor

The constructor is a function that runs when an object is created from a class; this code is the first to execute when you make an instance of an object, or the first function to run in your project if in the Document Class.

It calls the necessary functions to start the game. Check those functions in the next steps.

 
public final function Main():void 
{ 
	loadXML('q&a.xml'); 
    addListeners(); 
}

Step 19: Load XML

This function uses the xmlLoader instance to load the file specified in the parameter. The listener added to the object will call the a function when the load is complete.

 
private final function loadXML(src:String):void 
{ 
	xmlLoader = new URLLoader(new URLRequest(src)); 
	xmlLoader.addEventListener(Event.COMPLETE, parseXML); 
}

Step 20: Parse XML

The next code assigns the data loaded from the external file to the variable, this will allow us to use that data in any part of our class.

 
private final function parseXML(e:Event):void 
{ 
	xml = new XML(e.target.data); 
}

Step 21: Prepare Game

When the user clicks on the Start button the following code is executed:

 
private final function prepareGameScreen(e:MouseEvent):void 
{ 
	changeQuestion(); 
	 
	TweenNano.to(menuScreen, 0.4, {y:stage.stageHeight + (menuScreen.height * 0.5), onComplete: removeMenuScreen});

This will tween the main screen to make it invisible by the user and then remove it, it also calls a function that will load the first question.


Step 22: MovieClip Button Mode

We can't access instance names of a TextField inside a button, but using MovieClips will remove the hand cursor that indicates that the element is interactive. The next code will make the hand cursor appear when hovering over any of the buttons.

 
aPanel.button1.buttonMode = true; 
aPanel.button1.mouseChildren = false; 
aPanel.button2.buttonMode = true; 
aPanel.button2.mouseChildren = false; 
aPanel.button3.buttonMode = true; 
aPanel.button3.mouseChildren = false; 
aPanel.button4.buttonMode = true; 
aPanel.button4.mouseChildren = false;

Step 23: Change Question

This is the main function in this class, it performs most of the operations that will load and handle the loaded questions. Read through the next steps to see its behavior.

 
private final function changeQuestion(n:int = 0):void 
{

The arguments here determine the question to be loaded and the correct answer.


Step 24: Check Total Questions

These lines check if there is a next question; if there isn't, it calls the gameOver function.

 
if(nextQ == xml.children().length()) 
{ 
	gameOver(); 
}

Step 25: Set Possible Answers

If there is another question, the TextFields in the question panel are filled with the corresponding information.

 
else 
{ 
	/* Set Question and Answers */ 
	 
	qPanel.questionTF.text = xml.children()[n]; 
	aPanel.button1.oneTF.text = xml.children()[n].@option1; 
	aPanel.button2.twoTF.text = xml.children()[n].@option2; 
	aPanel.button3.threeTF.text = xml.children()[n].@option3; 
	aPanel.button4.fourTF.text = xml.children()[n].@answer;

Step 26: Set Correct Answer

The correct answer parameter is passed to a variable to determine when the button clicked was the correct one or not. At the moment we always use the fourth answer as the correct one.

 
/* Set correct answer */ 
 
answer = 'button4'; 
 
/* Move to next question */ 
 
nextQ = n+1;

Step 27: Tween Panels

When the questions and answers are set, the panels are shown.

 
TweenNano.from(qPanel, 1.5, {x: -qPanel.width, ease: Elastic.easeInOut}); 
TweenNano.from(aPanel, 1.5, {y: stage.stageHeight + aPanel.height, ease: Elastic.easeInOut});

Step 28: Update Question Counter

This line changes the value of the question counter in the bottom-right corner, it shows the current question and the questions left for the quiz to end.

 
qCounterTF.text = String(nextQ) + '/' + xml.children().length();

Step 29: Check for Images

If the parameter image in the xml has a value, the image in the url is loaded.

 
if(imgLoader != null) 
{ 
	removeChild(imgLoader); 
	imgLoader = null; 
} 
 
if(xml.children()[n].@image != '') 
{ 
	imgLoader = new Loader(); 
	imgLoader.load(new URLRequest(xml.children()[n].@image)); 
	imgLoader.contentLoaderInfo.addEventListener(Event.COMPLETE, displayImage); 
}

Step 30: Display Image

Then is placed in stage and tweened to its position.

 
private final function displayImage(e:Event):void 
{ 
	imgLoader.x = 360; 
	imgLoader.y = -imgLoader.height; 
	addChild(imgLoader); 
	TweenNano.to(imgLoader, 1.5, {y:67, ease: Elastic.easeInOut}); 
}

Step 31: Check for Sounds

If the parameter sound in the xml has a value, the file in the url is loaded.

 
if(sndLoader != null) 
{ 
	sndLoader = null; 
} 
 
if(xml.children()[n].@sound != '') 
{ 
	sndLoader = new Sound(); 
	sndLoader.load(new URLRequest(xml.children()[n].@sound)); 
	sndLoader.addEventListener(Event.COMPLETE, playSound); 
}

Step 32: Play Sound

When the load in complete, the sound is played.

 
private final function playSound(e:Event):void 
{ 
	sndLoader.play(); 
}

Step 33: Remove Menu

This is the function that will remove the menu screen from the display list and declare the variable as null to let it be cleared from memory.

 
private final function removeMenuScreen():void 
{ 
	removeChild(menuScreen); 
	menuScreen = null; 
}

Step 34: Show Credits

The following code calls the credits screen, it uses a variable to instantiate the MovieClip and then tween it to the stage.

 
private final function showCreditsScreen(e:MouseEvent):void 
{ 
	credits = new CreditsScreen(); 
	credits.x = stage.stageWidth * 0.5; 
	credits.addEventListener(MouseEvent.MOUSE_UP, removeCredits); 
	 
	addChild(credits); 
	TweenNano.to(credits, 0.3, {y: stage.stageHeight * 0.5}); 
}

Step 35: Remove Credits

This lines will tween out and destroy the credits screen when clicked.

 
private final function removeCredits(e:MouseEvent):void 
{ 
	TweenNano.to(credits, 0.5, {y:-credits.height, onComplete: function():void{removeChild(credits); credits = null;}}); 
}

Step 36: Check Answer

When the user clicks on an answer this function is executed. It will check whteher the selected answer is correct or not and increase the appropiate counter. Then a new question is loaded.

 
private final function checkAnswer(e:MouseEvent):void 
{ 
	if(answer == e.target.name) 
	{ 
		ca++; 
		changeQuestion(nextQ); 
	} 
	else 
	{ 
		wa++; 
		changeQuestion(nextQ); 
	} 
}

Step 37: Game Over

If there are no more questions to load, the game over function starts. It will display the game over screen add a listener to it to restart.

 
private final function gameOver():void 
{ 
	var over:GameOver = new GameOver(); 
	 
	over.x = 15; 
	over.y = 15; 
	over.addEventListener(MouseEvent.MOUSE_UP, restart); 
	addChild(over); 
	 
	over.caTF.text = String(ca); 
	over.waTF.text = String(wa); 
	 
	TweenNano.from(over, 0.5, {x:stage.stageWidth}); 
}

Step 38: Final Score

The final score will be shown in the game over screen, the next line sets it.

 
over.scoreTF.text = String(Math.floor((ca / xml.children().length()) * 100)) + '%';

Step 39: Restart Function

The next funcion will reload the swf, restarting any variable and method.

 
private final function restart(e:MouseEvent):void 
{ 
  		navigateToURL(new URLRequest(stage.loaderInfo.url), '_level0'); 
}

Step 40: Set Main Class


Add the class name to the Class field in the Publish section of the Properties panel to associate the FLA with the Main document class. You can now run the Quiz.


Step 41: Shuffle the Answers

You may have noticed that the fourth answer is always the correct one. We can fix that by putting the answers into an array and then shuffling it, see this guide for more information. Change the appropriate code in changeQuestion() like so:

 
/* Set Question and Answers */ 
 
qPanel.questionTF.text = xml.children()[n]; 
 
var answers:Array = [ 
						xml.children()[n].@option1,  
						xml.children()[n].@option2,  
						xml.children()[n].@option3,  
						xml.children()[n].@answer 
					]; 
var shuffledAnswers:Array = new Array(answers.length); 
 
var randomPos:Number = 0; 
var numberOfAnswers:int = answers.length; 
for (var i:int = 0; i < numberOfAnswers; i++) 
{ 
	randomPos = int(Math.random() * answers.length); 
	shuffledAnswers[i] = answers.splice(randomPos, 1)[0]; 
} 
 
aPanel.button1.oneTF.text = shuffledAnswers[0]; 
aPanel.button2.twoTF.text = shuffledAnswers[1]; 
aPanel.button3.threeTF.text = shuffledAnswers[2]; 
aPanel.button4.fourTF.text = shuffledAnswers[3]; 
 
/* Set correct answer */ 
 
if (aPanel.button1.oneTF.text == xml.children()[n].@answer) answer = 'button1'; 
if (aPanel.button2.twoTF.text == xml.children()[n].@answer) answer = 'button2'; 
if (aPanel.button3.threeTF.text == xml.children()[n].@answer) answer = 'button3'; 
if (aPanel.button4.fourTF.text == xml.children()[n].@answer) answer = 'button4'; 
 
/* Move to next question */ 
nextQ = n+1;

Conclusion

Try adding your custom questions and graphics, remember that you only need to modify the XML file to make another Quiz!

I hope you liked this tutorial, thank you for reading!

Advertisement