instruction_banner

by Kevin Schmitt

The Mother of All Flash Quiz Engines, Part 2

One might naturally assume that a series of articles about building a Flash quiz engine may actually impart some knowledge about, oh, say, Flash. With that in mind, in this installment we’re going to rectify the absence of any Flash in part one by firing up Flash and writing some ActionScript 3, with the exciting goal of loading the XML document we produced last time. Without further ado, let’s dive right in.

A word (actually, two paragraphs) about Flash and AS3

Adobe, the inheritors of the Flash authoring tool after the takeover of Macromedia a few years back, now offers many ways to create what, in broad terms, is known as “Flash.” However, we’re really talking about the SWF format, which is the end product of any tool purporting to author Flash content. Adobe offers Flash CS4 Professional, Flex Builder 3 (soon to be renamed Flash Builder and bumped to version 4), and the forthcoming Flash Catalyst, which all can output interactive SWF files. If you’re so inclined, you can even download the free Flex SDK, and with the help of nothing more than a text editor, write ActionScript 3 and compile to SWF without spending a dime. Throw in some third party SWF production tools, and the Flash landscape has the potential to be vexing, to say the least.

In order to ward off much of this confusion, the way we’re going to proceed for the remainder of this series is to work completely within the Flash authoring tool itself, currently known as Flash CS4 Professional. This way, we’ll be able to create completely self-contained source files (in Flash’s native FLA format), in which we can visually lay out graphic elements as well as write all the ActionScript necessary for our engine right in Flash’s timeline. Coding purists may be eliciting a groan at this point, but the idea here is to get you started on the journey to understanding and using ActionScript 3 in your own projects, and there’s no simpler way to begin than typing away in Flash’s Actions panel. The downside is that Flash CS4 is not free (far from it), but Adobe does offer a 30-day tryout version (a link to which which can be found in the related links sidebar).

A quick note on ActionScript

What this series is NOT going to be is a comprehensive overview of ActionScript 3, but suffice it to say we will be going over some AS3 fundamentals as we go along. Now, anyone who is at least passingly familiar with ActionScript 2 may have taken one look at the changes present in AS3 and bellowed forth a hearty “no way.” Indeed, one of the main knocks on AS3 is that non-developers find the changes nigh unapproachable. Yours truly was squarely in that category once upon a time, but after bearing down and just getting it done, the switch to AS3 has proven to be well worth the effort. Enough with the pep talk, such as it is — let’s go over the couple of things that would be good to know from the get-go, which we’ll be exploring more as we get into further installments. In a nutshell, if you only take away two things about ActionScript 3, make it these:

  1. Just about every interaction in AS3 boils down to thinking of the relationships between objects and events
  2. The more you understand AS3’s display list, the easier time you’ll have

We’ll expound on both of these points as the series unfolds. In the meantime, if you want a more in-depth look at core AS3 principles before you dive in, check out the related links in the sidebar.

As far as XML goes, If you count yourself amongst the unlucky legion of Flash folk who had the misfortune of trying to work with XML in ActionScript 2, you’ll find yourself nodding along when I state that AS3’s handling of XML is light years ahead. AS3 supports the ECMAScript for XML specification (E4X for short), which sounds scary but basically means that once an XML document is loaded into your Flash movie (or directly declared as a variable), you can drill down to the part of the document you want just by stringing out a very logical path, almost like an outline. It’s quite natural to work with, and again, just so much better than what came before. Got all that? Good.

Deconstructing our XML document

First, let’s take a look at the XML document we made last time, which will eventually serve as the template for the types of quizzes our yet-to-be-built engine will read and display:

<!--mode types: inline, reveal, or submit-->
<quiz mode="inline" timer="0">
	<item>
		<question>The first question is a true/false question.</question>
		<answer correct="true">True</answer>
		<answer>False</answer>
		<explanation>When a question has one answer called "true" and one answer called "false," it is a true/false question.</explanation>
	</item>
	<item>
		<question>Does this question have three possible answers?</question>
		<answer correct="true">Yes</answer>
		<answer>No</answer>
		<answer>Maybe</answer>
		<explanation>Some questions have two answers, some have four, but this one has three.</explanation>
	</item>
	<item>
		<question>How many possible answers does this question have?</question>
		<answer>One</answer>
		<answer>Two</answer>
		<answer>Three</answer>
		<answer correct="true">Four</answer>
		<explanation>Four is an excellent number in general, so we are very fortunate that it is the right answer in this case.</explanation>
		<media>http://url/path/to/mediafile.jpg</media>
	</item>
</quiz>

Let’s get this thing into Flash, shall we? Launch Flash CS4 and create a new Flash File (ActionScript 3.0) as shown in Figure 1. For now, you can keep all the default settings.


Figure 1

By default, the Timeline will contain a solitary blank frame (fig. 2). Feel free to double-click the “Layer 1″ label and rename the frame to “actions.”


Figure 2

Next, make sure frame 1 of the “Layer 1″ or “actions” layer (whichever yours is named) is selected, and then select the Actions panel from the Window menu (fig. 3).


Figure 3

For the unfamiliar, take a good, long look. We’re going to be spending a lot of time with our new buddy the Actions panel (fig. 4).


Figure 4

You don’t have to type what I did in Figure 4, but do take note: that one line of code contains the venerable trace command, which we’ll be using profusely as things unfold. Now, as I alluded to before, we need to load in our XML file in order to read and use its contents, so go ahead and copy the XML code shown above into a text editor, and save it as quiz.xml to your local drive. While you’re at it, go ahead and save your blank Flash movie as xmltest.fla in the same directory as the XML document.

Let’s write our first bit of ActionScript. In the empty Actions panel, enter the following text:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
var quiz:XML;
var xloader:URLLoader = new URLLoader();
 
xloader.addEventListener(IOErrorEvent.IO_ERROR, onError);
xloader.addEventListener(Event.COMPLETE, onLoaded);
xloader.load(new URLRequest("quiz.xml"));
 
function onError(e:IOErrorEvent):void {
	trace("An error occured when attempting to load the XML:\r" + e.text);
}
 
function onLoaded(e:Event):void {
	quiz = XML(e.target.data);
	parseXML();
}
 
function parseXML():void {
	trace(quiz);
}

It’s OK if you want to copy and paste, but getting used to typing ActionScript out is always a worthwhile endeavor. In any event, once this code is in the Actions panel, go ahead and test the movie (Control:Test Movie), and you should see something similar to Figure 5 appear in your Output panel:


Figure 5

While that output looks suspiciously like our source XML file (which is a good thing), you may be asking yourself the larger question: just what is this pile of hooey that was just heaped upon you, the unsuspecting reader? In a nutshell, the code does the following:

  1. Creates the variables that represent the XML file and the loader used to bring it into the movie
  2. Establishes listeners that react to specific events
  3. Issues instructions for what to do once the XML file has been loaded in

Remember back a bit when I mentioned AS3 is all about the relationship between objects and events? Well, here is our first evidence of that. Let’s go through the code in more detail, and hopefully this will become a little more clear:

1
2
var quiz:XML;
var xloader:URLLoader = new URLLoader();

In these first two lines, we’re defining some variables. Variables in AS3 have to be declared with the var keyword, followed by the name you want to assign to the variable, followed by a colon, followed by the type of variable you are declaring, followed (optionally) by either the new constructor or the initial value of the variable. In this case, the first variable is the XML type named quiz, to which we’ve assigned no initial value. In this state, it doesn’t really “exist” yet, but fear not — we’ll rectify that soon. The second variable, xloader, simply creates a new URLLoader, which is AS3’s required mechanism for loading — you guessed it — content from a URL. Think of these variables as objects, items with “tangible” heft in the AS3 world, the noun of the sentence, if you will.

4
5
6
xloader.addEventListener(Event.COMPLETE, onLoaded);
xloader.addEventListener(IOErrorEvent.IO_ERROR, onError);
xloader.load(new URLRequest("quiz.xml"));

We have our nouns; now we need to add some verbs. These are the events in the object/event relationship, and in AS3 they take the form of the addEventListener method (or function; we’ll use these terms interchangeably). While we’re not directing quiz to do anything yet, we do need to tell xloader to do three things:

  1. What to do if the XML doesn’t load
  2. What to do when the XML has successfully loaded
  3. Load the XML, thereby giving the first two something to listen for

On line 4 we’re hedging our bets a bit by telling xloader to call a custom method, onError, just in case something goes wrong (IOErrorEvent.IO_ERROR, which is indicative of AS3’s event handler syntax). In line 5, we’re taking care of that second item by telling xloader to call another custom method, onLoaded, which fires when the load is complete (hence the Event.COMPLETE argument). With those listeners established, we can then direct xloader in line 6 to go ahead and load our XML file that we saved a while back.

8
9
10
function onError(e:IOErrorEvent):void {
	trace("An error occured when attempting to load the XML:\r" + e.text);
}

Moving on to the custom methods mentioned earlier, this first function traces out an error should the XML not load. This should be fairly straightforward, but a couple of notes are in order since this is our first function. Specifically, the e:Event and the void portions have the most capacity for confusion. In the case of the former, each function you write that serves as a handler for an event listener must contain an argument that is typed to the specific event that is calling it. In other words, listeners and events need to “match up” in order for the code to be considered valid. Since onError is the handler for the error listener, the argument e must be typed to an IOErrorEvent. If this function gets called, the Output window would trace out the text specified, as well as whatever the parameter text is of argument e.

As for the void, in AS3 you need to specify whether the function is supposed to return anything. For example, if I created a function that figured out the current time, and called it whatTimeIsIt, I could specify that it return a String (piece of text) so that I could just call the whatTimeIsIt function anytime I needed to insert the current time as text. Since this function doesn’t need to return a value, void gets tacked on there.

12
13
14
15
function onLoaded(e:Event):void {
	quiz = XML(e.target.data);
	parseXML();
}

This function is the one that should be called if everything goes right, which, in this case, is after the XML has loaded successfully. We’re only doing two things here: in line 14, we’re taking the contents of the XML file (e.target.data), making sure those contents are “cast” as XML (hence the need to “wrap” it in XML()), and assigning it to the quiz XML variable we declared earlier. At this point, our formerly external XML file is now defined as an internal variable in our Flash movie, one which we can refer to as often as we wish. Second, line 15 simply calls another dedicated function, parseXML, which will handle the heavy lifting of going through the XML file. Speaking of which…

17
18
19
function parseXML():void {
	trace(quiz);
}

It’s not doing any heavy lifting just yet, though. For right now, allparseXML is doing is tracing out the contents of the quiz variable to the Output panel, which, as you saw back in Figure 5, shows the correct XML contents. We’ll make a mark in the “good” column on that one and call it a session.

Next time…

I think ~2,000 words is enough for this installment, so let’s map out the strategy for next time. The plan is to go through the ins and outs of pulling data from our quiz variable using AS3’s E4X syntax, which will lay the foundation for setting up and displaying the various types of quizzes the engine will display. In the meantime, feel free to post any questions or leave comments below, and we’ll pick this up in our next issue.

One Response to “The Mother of All Flash Quiz Engines, Part 2”

  1. JimV says:

    This is fun keep it coming.

Our Sponsor