In this tutorial, I will show you:
So, roll up your sleeves and follow my guidance. Let's go!
1. Open a new Flash document and save it in a new folder — make sure that this folder is completely empty. Only Flash files and data files (text and XML) will be stored inside it. This is a good practice, to avoid confusion. Don't save your Flash file somewhere where there are other .fla files. Keep it clean and simple.
2. Download the zip file that I prepared for you. Unpack it. You will find two files that were inside it: guessword.txt and words.xml. Place both of them in the folder where you saved your new Flash document. If you want, take a look at them now, but really there is no need — I will discuss and explain them in extensive detail later.
3. Back to your Flash document, select Modify > Document to access the Document Proprties panel. In the Dimensions section, enter 500 pixels for both width and height fields. Click OK.

Of course, if you want, you can pick any other dimensions for your Flash movie to suit your needs, but for the sake of simplicity and easier work, make them as I suggested above. These dimensions will make it easier for you to follow this tutorial and place the graphic elements accordingly.
4. Select the Pencil tool (Y). In the Property inspector, choose black for the color, Solid as line type and a line thickness of 5.
![]()
5. Draw a hangman, complete with gallows. Its total dimensions (top to bottom, left to right) should be about 130 pixels by 150 pixels.

Pay attention to the following: the drawing should be composed of 9 separate lines, like this:

It isn't strictly necessary to do this, but if you follow my suggestion, you will find the animation work that comes next much easier to follow. Also, if you want, you can make more parts for the hangman: the one used in this lesson is made up of nine parts, which allows the player to make nine errors before the game is over. But I will leave that up to you — decide the level of difficulty that you want to make for this game, and then draw the figure accordingly.
6. No matter how you drew your hangman, do the following now: select the whole drawing with the Selection tool (V).

7. Press F8 (or select Modify > Convert to Symbol) to make a symbol out of this drawing. In the window that shows up, select Movie clip as type, call it hanging sequence and click OK.

8. Position your new movie clip (using the arrow keys or your mouse) in the upper right part of your document.

9. Double-click on the hanging sequence movie clip with the Selection tool (V) to enter inside it. To be sure that you are really inside the movie clip symbol, take a look above the stage, it is clearly written there:
![]()
10. Right-click on frame 2 of the only (so far) layer of the movie clip and select Insert Keyframe. Your movie clip's timeline should now look like this:
![]()
11. On the keyframe that you have just created, click once on an empty part of the stage to unselect the drawing. Then, select a leg of the figure by clicking on it with the Selection tool (V), and then hit Delete or Backspace to erase it.

12. Insert a new Keyframe in frame 3 of the current layer, just like you did in step 10.
![]()
13. Repeat the procedure you did in step 11, this time erasing the second leg of the character.

14. Repeat this procedure, until you have 6 new keyframes, meaning 9 keyframes in total. On each new keyframe you should erase a part of the drawing. The image below shows how the drawing should look like in each of the new keyframes.

15. Once you have finished the previous step, select all the nine keyframes.
![]()
16. Now, right-click on any of the selected (blackened) keyframes and select Reverse Frames from the menu that shows up. Apparently, nothing has changed. But wait just a little more, you will see why this was done.
17. With all the keyframes still selected, click on them and move them forward by 1 frame, like the sequence of images below shows:

Ok, let me explain you now why all of this had to be done. When a player begins playing the game, the drawing must not be visible at all, because no mistake has been made yet. And when (if) the first mistake is going to happen, the first part of the drawing — the vertical line of gallows — has to appear.
And that's why you had to reverse the order of the keyframes — you began by drawing the full image, on the first keyframe. That was done because it is much, much easier to create the complete drawing first and then just erase it part by part, until you arrived at a single line. Imagine drawing the entire thing frame by frame: it is a waste of time. By doing as I had laid the procedure out, you save time and just click and delete as you go along.
18. Lock this layer (you are still inside the movie clip, remember) and call it sequence. Make a new layer above it and call it actions.

19. Click on the first (and only) keyframe of the actions layer to select it.

20. Select Window > Actions (shortcut key: F9) to open the Actions panel. Insert the following line of code inside:
stop();
The stop() action will prevent this movie clip from going
forward. As you know, all the animations in Flash loop endlessly by default,
unless you tell them otherwise via ActionScript. And this movie clip should
advance forward only if the player made a mistake. You will make this possible
later, when the main code is going to be written.
21. Click on the Scene 1 link above the layers to return to the main scene.
![]()
22. The hanging sequence movie clip which you just exited will be selected by default now. Go to the Property inspector and give it the Instance name hangman_mc.

23. Call the current layer (the only one so far) on the main scene hangman and lock it.
![]()
You shouldn't see anything inside your document right now, just the empty stage. This is perfectly ok, since the first frame of the hanging sequence movie clip is empty.
24. Make a new layer and call it text field.

25. Select the Text tool (T). Pick the following options in the Property inspector (see numbers on the image below):

Most of these options are self-explanatory. I just want to point out two options: the _sans generic font type and the Use device fonts rendering option.
The first one is a wise thing to do, because it makes the user's operating system pick the default sans serif font. Basically, this will allow for all users to see almost the same thing. If you had chosen the Arial font for example, some Mac users wouldn't see it. Likewise, if you are working on a Mac and you want to select Helvetica, most Windows users won't see this font, because it doesn't come pre-installed with the operating system. The _sans option automatically selects the default sans serif font on any system.
The Second option, for using the device fonts, means that your final SWF file intended for the Web will be much smaller in size. Had you selected any other option, like Anti-alias for animation or readability for example, you would have to select a non-generic font family and after that, embed the characters in your SWF document. Embedding makes the SWF file larger in size, because Flash must store the vector shape data of the font's characters into itself.
Sure, if you need a specific design with a specific font in mind, you may want to embed the font data into your Flash movie. If you choose this method, every single user will see the font you chose, regardless if it's installed on their system or not.
26. Click and drag out a long text field on the stage, somewhere along its vertical middle point. It should span the whole stage width. When done, press Esc on your keyboard to exit the text field.

Now, you should be aware of a property here: the number of characters that can appear in the text field. If you have made it as wide as I did, with the same characteristics such as font type an size, it should be able to display about 34 characters. Most of the words used in a hangman game don't have such a high letter count, so you should be safe with the text field that you just created.
On the other hand, if you plan to make your game include some less commonly used words, like latin animal species names, words used in science, etc, you should either make your text field (and the size of your document) wider, or pick a smaller font size. If you go for the second option, don't pick a font size that is too small, because the word and the guessed letters must be clearly visible.
27. With the dynamic text field still selected, go again to the Property inspector and give it an Instance name: call it guessWord_txt.

That's it for the text field. It's good and ready to be manipulated with via ActionScript.
The title of this section mens the following: you will create a movie clip which will be used at runtime. At runtime means while the SWF movie is running. Instead of creating each letter button (for the player to press — to guess a letter in the word) separately on stage, you will save lots of time by making a single movie clip, and then writing some ActionScript code that will create all the buttons for the entire alphabet.
28. Lock the current layer and make a new one: call it start screen.

This layer will in fact host the starting screen for the game. It is here that you will create the movie clip with the text field, since it will be erased anyway. This movie clip is going to be stored in the Library, so it really isn't necessary to create a separate layer for it.
29. Select the Rectangle tool (R) and draw a 31 by 31 pixel borderless square on the stage. If you prefer buttons with borders, by all means do make a border. Pick any color you like.
![]()
30. Select the square and press F8 to convert it into a symbol. Pay attention to the following: select Movie clip as type and make sure to select the upper left corner for the Registration point. Enter letter button as name and click OK.

Selecting this particular registration point will make the positioning of the many letter buttons much easier later.
31. Double-click the newly made movie clip on the stage to enter inside it.
32. Once inside it, call the first layer background and lock it. Make a new layer and call it text field.

33. Choose the Text tool (T). In the Property inspector, all the options should be the same as the ones in step 25 of this tutorial, except one: the font size. Make it smaller, change it to 18.
Click and drag over the square and make a text field that covers almost all of it. Press Esc to exit the text field.
![]()
34. Go to the left side of the Property inspector and assign an Instance name to the text field: name it letter_txt.

35. Click on the Scene 1 link to go back to the main scene and timeline.
![]()
36. Delete the movie clip that you have just made from the stage. It is stored in the Library, so there is no need to have it on the scene and/or assign it an Instance name. You will pull it out dynamically, thanks to an identifier. You will see how to do just that in a moment.
37. Open the Library if it isn't open already (Window > Library). You will see your letter button movie clip nicely sitting there, along with the hanging sequence movie clip.
38. Right-click on the letter button movie clip and select Linkage from the menu.

39. The Linkage Properties window will appear. Check the Export for ActionScript option. The Export in first frame option will automatically follow. In the Identifier field write letterButton and click OK.

This movie clip is now ready to be manipulated via ActionScript, thanks to the Identifier name you gave it and the Export for ActionScript option.
The Export in first frame option means (if checked, like in this case) that this movie clip will begin to load before any other content in your SWF. This can cause problems with large, graphics-intensive movie clips, because if you happen to have a preloader in your SWF, it won't be visible until that particular movie clip has completely loaded. But there is a simple solution to that: make a SWF with just a preloader in it, which in turn loads the main SWF with the movie clip in question inside it. Here, you don't have to worry about that because the letter button movie clip's size is around 180 bytes :) !
40. Still in the start screen layer, select the Rectangle tool (R). Draw a big square on the stage, the width and height of which should be about 430 pixels.

41. Convert this square into a Movie clip symbol, call it start screen and click OK. The registration point for this one isn't important.
42. Double-click on the newly made movie clip to enter inside it.
43. Inside the start screen movie clip, call the first layer (containing the square) background and lock it. Make a new layer and call it play button.

44. In this layer, create a 160 by 50 pixel rectangle, with round corners if you like, choosing any colors you like. Place it over the lowest third of the background square and center it horizontally.

45. Use the Text tool (T) to write the message "Play!" on top of it. This time, choose any font you like and make sure that you have selected Static text for your text field. This is a design element, not a dynamic one.

46. Using the Selection tool (V), select both the rectangle and the text field. Press F8 to convert it into a Movie clip — call it play it again sam or whatever you like :) and click OK.
47. This movie clip will need an Instance name, so that you can tell it via ActionScript what to do when a player presses it. So do just that: name it play_mc.

48. Lock the play button layer and make a new one above it, with the name message.

49. Select the Text tool (T) again. Make sure that you have selected Dynamic text. Make the same choices for this tool as you did earlier in step 25, with one change: select the Multiline option, NOT the Single line one.
50. Create a big text field on the stage, that goes from the top of the background square, down to the play button and spans the square from side to side. Hit Esc to exit the text field. You can see the text field's blue border in the image below.

51. This text field will display the welcome message, with a piece of dynamic data inside it, so it needs an Instance name. Call it message_txt.

52. Go back to the main scene and give the start screen movie clip the Instance name startScreen_mc.

53. Lock the start screen layer.

Fine! That's it concerning the graphical elements of the hangman game. Whew! :) What follows is pure ActionScript.
54. Make a new layer and call it actions. Lock it, since a layer in Flash doesn not need to be unlocked for you to enter ActionScript code inside it. Click on the layer's first (and only) keyframe to select it for code inserting.

55. Select Window > Actions to open the Actions panel. Insert the following ActionScript code inside it:
guessWord_txt._visible = false;
var welcomePart1:String = "Welcome to the hangman game! To, win you must try to
guess the name of ";
var welcomePart2:String = ". Press the play button below to start.";
var guessTopic:LoadVars = new LoadVars();
guessTopic.onLoad = function(success:Boolean) {
if (success) {
startScreen_mc.message_txt.text =
welcomePart1+this.myTopic+welcomePart2;
} else {
startScreen_mc.message_txt.text = "The data failed to load.
I am sorry!";
}
};
guessTopic.load("guessword.txt");
The first line effectively hides the guessWord_txt text field by
setting its _visible property to false. It will be
made visiblke once the player presses the play button, the functionality of
which will be defined later.
The second and the third line define the welcomePart1 and
welcomePart2 variables. Both are defined as String
variables, which means that they will hold text values. And these text values
are assigned to them immediately. They are, respectively:
They may appear a little strange. If you look at them closely, you will see that the first one ends with a space and that the second one starts with a fullstop, followed by a space and another sentence. This is because they will both be parts of the welcome message, once the game loads. The third piece of information for the welcome message will be loaded from an external text file.
The main reason for doing so is that once you finish the SWF file, with all the ActionScript code that you are going to add, you will have a completely dynamic game at your disposal. You won't have to edit the .fla file anymore and re-export it as a .swf. If you ever want to change the topic of the game (the type of word to be guessed) and the words, all you will have to do is edit the text and XML files, upload them to your website, and that's it! That's a much, much better solution than cementing the values inside the Flash file and having to re-edit it every time you want to have a different game.
Suppose that you want the player to guess the name of an animal. The welcome message would be as follows: "Welcome to the hangman game! To, win you must try to guess the name of an animal. Press the play button below to start." The two bolded words, "an animal", are placed in the guessword.txt file that you have downloaded at the beginning of this tutorial. Why both the article and the noun, and not just "animal"?
Well, suppose that you are going to change the game so that the player has to guess the name of a city. If you had put the article "an" into the code of your .FLA file, the resulting message would be "...guess the name of an city", which is bad English. So it is logical that both the type of word to be guessed an its article should be put in the external text file. Thanks to this, you can just change "an animal" into "a city".
And now comes the chunk of code that loads the text file and
performs different actions, depending on whether the external text file was
loaded successfully or not. The first line creates a new LoadVars
object, which is used to load external variables into Flash or
export variables to an external source:
var guessTopic:LoadVars = new LoadVars();
Like with the majority of objects in Flash, you can't create them separately,
like this: new LoadVars(). This won't work at all. You must
create a variable (guessTopic in this case) and then
store an instance of the object that you wish to use inside that
variable, exactly like is shown in the line of code above. Since you
are creating a new LoadVars object, the type of the
guessTopic variable is set to LoadVars, of course (guessTopic:LoadVars).
Once you do that, for all practical purposes, you can say that the
guessTopic variable is in fact an instance of the LoadVars
object.
Let me show you now how to load variables from an external source (the
guessword.txt file in this case) using the LoadVars object
that you just created. Before loading the actual data, it is
considered the best practice to tell Flash first what to do once the
loading has finished, and then order it to load the data.
To do this, you must use the onLoad event handler
of the LoadVars object.
guessTopic.onLoad = function(success:Boolean) {
if (success) {
startScreen_mc.message_txt.text =
welcomePart1+this.myTopic+welcomePart2;
} else {
startScreen_mc.message_txt.text = "The data failed to load.
I am sorry!";
}
};
guessTopic.load("guessword.txt");
REMEMBER In ActionScript, an event handler is a function that is called and executed automatically when a particular event occurs. An event is something that happens in your movie: the user clicking a button, a sound finishing playing, the mouse being moved and so on. By inserting event handlers into your code, you enable Flash to react when an event has transpired — you tell it what to do.
So, the onLoad event handler reacts when external
variables (variables stored in guessword.txt file in this
particular case) have been converted into object properties. To
better understand this, have a look at the guessword.txt file. Open it
and look at its contents. You will see this:
myTopic=an+animal
myTopic is the name of the variable, and
an+animal is its value. You have certainly noticed
the plus (+) sign between these two words. It is used to denote spaces in a file
that is going to be loaded via the LoadVars object. You can't just
put a simple space between the value's words, you must separate
them with a plus sign.
If you are going to create a project where you will need multiple variables with different values, your text file's contents would look like this:
myName=John&mySurname=Smith&myAddress=Flash+plaza&myCity=Flashville&myCountry=Flashia
As you can see, the various variables with their respective values are separated by ampersand signs (&). In programmer's jargon, these variables and their values are called name/value pairs.
I mentioned above that once loaded, these external variables will be
converted into object properties. What this means is that the myTopic
variable will become a property of the guessTopic LoadVars object.
Thanks to that, you can retrieve the value of this variable by referencing it
like this: guessTopic.myTopic. And from that,
Flash would read the value, which "an animal" in this case.
Fine! Now that you understand how the LoadVars object loads external
variables into Flash, let me show you how it will react once the data has been
loaded. As you can see, the first line calls the guessTopic
object's onLoad event handler, with a parameter passed to it:
success. This parameter is of the Boolean type, meaning
that its value can be either true or false.
guessTopic.onLoad = function(success:Boolean) {
if (success) {
startScreen_mc.message_txt.text =
welcomePart1+this.myTopic+welcomePart2;
} else {
startScreen_mc.message_txt.text = "The data failed to load.
I am sorry!";
}
};
This parameter is necessary, because you must check if the
variables have been loaded and converted into properties of the guessTopic
LoadVars object. The contents of the event handler function do just that (they
are located between the function's curly braces: { and }).
Here, the contents consist of an if/else conditional statement.
If the value of success turns out to be true
(meaning the data has been loaded and converted successfully), the welcome
message will be displayed. If it turns out as false, an error
message will be displayed. In both cases, the message will be displayed in the
message_txt text field, which is situated inside the
startScreen_mc movie clip. In the first case (when success
equals true), the message will be composed of three variables'
values:
welcomePart1+this.myTopic+welcomePart2
You have already defined and seen the values of the variables
welcomePart1 and welcomePart2. The middle one is reffered to
as this.myTopic. The keyword this points to
the guessTopic object itself, because it is written inside
the object's onLoad event handler function. And, just as I said
previously, the myTopic property is the variable that has been
loaded from the external text file and converted into a property of the
guessTopic object. Its value: "an animal". Without the quotation marks,
of course — I have written them here to better distinguisg the value from the
surrounding text. So the welcome message will inform the player what is the
topic of the game (an animal, a city, a car, etc).
And if the loading fails, the "I'm so sorry" message is displayed :). If the loading fails, it is basically beyond your control. The loading error could be due to the problems the player may have with his Internet connection, his firewall and so on. The best thing that you can do is to notify the player that the loading has failed.
IMPORTANT The one thing that you must pay attention to is to place the text file (guessword.txt) in the same folder on your website where the final SWF file (the hangman game Flash movie) is going to be. Also, make sure that the HTML file — the page inside which the Flash SWF file will be embedded is also in this same folder. The same goes for the XML file.
These files do not necessarily have to be in the same folder — I did it like this for the sake of simplicity. You can even put the files on different web servers if you want to, but some additional steps must be made then for the game to function properly. And I don't wish to discuss this subject here, because this tutorial would span tens of pages. Instead, I will save that for another tutorial, where the cross-domain file loading policy will be explained in more detail.
Finally comes the line that actually tells Flash to load data from the external text file:
guessTopic.load("guessword.txt");
But... as you may have noticed, there is no preloader here. Why? Because the guessword.txt text file has a size of 17 bytes! Making a preloader for this tiny bit of data makes no sense at all. This file will load instantly even on a prehistoric 14.4 K modem connection!
56. Place the following code right after the one that you wrote previously:
var words:Array = new Array();
var alphabet:String = "abcdefghijklmnopqrstuvwxyz";
var chosenWord:String = new String();
var displayedText:String = new String();
var playAgain:Boolean = false;
Here, you are defining variables that will be used later. If possible, it is a fine practice that you define as many variables as possible in one place. This makes your code more clean and easy to edit later. Let's see what will each variable be used for:
words variable is of the Array type,
meaning it will store many values. Later, you will write
the code that will load the XML, find all the words for the hangman game and
put it inside this array.
alphabet holds inside all the letters of the English alphabet. This
is necessary for checking if a letter the player has
pressed is inside the hidden word or not. chosenWord variable (a String, too) will hold inside
itself a randomly picked word from the words array.
This is a must, otherwise the same word would pop up each time, which would
render the game useless. displayedText (again, a String) variable's value is the
text that will be shown in the guessWord_txt text field.
This is a piece of text that will consist of correctly guessed letters and
dots (or question marks) that fill in for the letters that haven't been
guessed by the player yet. playAgain is of the Boolean type and is set to
false. This variable will serve for checking if the
player has pressed the play button after finishing the first game
(whether she succeeded in guessing the hidden word or not) and subsequently,
resetting the guessWord_txt text field to its inital
state, with no text at all displayed inside it. 57. Append this code after the existing one:
var wordsLoader:XML = new XML();
wordsLoader.ignoreWhite = true;
wordsLoader.onLoad = function(success) {
if (success) {
parseWords();
} else {
guessWord_txt.text = "Sorry dude, the data just didn't
load.";
}
};
wordsLoader.load("words.xml");
As you can see, this code is similar to the previous one. At first, a new XML
object is created (wordsLoader). After that, the XML object's
onLoad event handler function is invoked, to check if the loading
succeeded or failed. Like before, this function has inside it an if/else
conditional statement. If success turns out as true,
the parseWords function is invoked (more on that function later).
If not, a "I am sorry" message will be displayed for the user. And after that,
the actual XML file gets loaded via the XML object's load
function.
Before I explain you the workings of the XML file, there is one line of code
that needs to be explained: the second one, with the ignoreWhite
property. The ignoreWhite property of an XML object can be
set to either true or false. By defining it as true,
you tell Flash to ignore all the white space found in the XML
file. Why is this necessary? Because white space in an XML file counts as data!
Fine. Now that the above piece of code is clear, let me tell you more about XML.
If you open the file words.xml (which you have downloaded at the start of this tutorial), you will see the following:
<?xml version="1.0"?>
<gamedata>
<word>dog</word>
<word>elephant</word>
<word>cat</word>
<word>lion</word>
<word>giraffe</word>
<word>wolf</word>
<word>ostrich</word>
<word>penguin</word>
<word>whale</word>
<word>raccoon</word>
<word>tiger</word>
<word>camel</word>
<word>snake</word>
<word>lizard</word>
</gamedata>
Before proceeding, you should know that XML stands for EXtensible Markup Language. It is a markup language that describes data. The great thing about the XML data format is that it is platform and operating system independent. This means that an XML file looks exactly the same, whether it is made or read on Linux, Mac, Windows or any other OS or platform. An XML file is basically a text file, with the extension .xml.
When making an XML file, you can use any basic text editor, like Notepad on Windows or SimpleText on a Mac. The important thing to keep in mind is that you should save this file with an .xml extension. Or, you can save it as a .txt file and later change the extension to .xml in your File Explorer.
An XML file can not do anything by itself — it is parsed (read, combed through, looked at) by various programs, browsers, server-side scripts (PHP, Java...) etc if they are enabled to do so. So, you can think of it as a very simple database — stored information.
Unlike an HTML file, where tags are predefined (<p>, <body>, <h1> etc), you are the one who defines the tags in an XML file. This means that you can call your tags any way you like, for example: <flash>, <mysuperbtag>, <anything> etc. But, there are some rules that must be followed. These are really simple, but very, very strict. You must abide by them. Here they are:
<?xml version="1.0"?>
This line tells the parser that it's, well, an XML file. This is not a tag, but just a declaration. So it appears only once, at the beginning of the XML file. Inside it, the version of XML is stated. Also, the character encoding of the file can be included, like this, for example:
<?xml version="1.0" encoding="UTF-8"?>
Since the XML file used in this tutorial is written in English, that additional parameter is not necessary.
<gamedata>
<word>dog</word>
<word>snake</word>
<word>lizard</word>
</gamedata>
Note: I have named each tag within the root element as "word" on purpose (you will see why later). For example, an XML file like this one would be perfectly valid too:
<computer>
<operatingsystem>windows</operatingsystem>
<processor>intel</processor>
<price>expensive</price>
</computer>
<gamedata>
<word>dog</word>
<word>snake
<word>lizard</word>
</gamedata>
<word>dog</word>
...while this would cause an error:
<Word>dog</word>
<diary>
<day>monday</day>
<entry>Another week, another monday</entry>
</diary>
...while this one is wrong:
<diary>
<day>monday<entry>
</day>Another week, another monday</entry>
</diary>
Here's another example. This would be fine:
<flowers><best>rose</best></flowers>
...and this would result in an error:
<flowers><best>rose</flowers></best>
<logentry day="monday">Another day at work</logentry>
...while this is incorrect:
<logentry day=monday>Another day at work</logentry>
Also, remember that you can insert as many attributes as you need.
These were the rules for writing proper XML. As you saw, they are really simple. You just have to respect them.
One more thing: as I said before, the white space in an XML file
counts as data. That's why you had to set the ignoreWhite
property to true in your ActionScript code previously. This can be
circumvented with another method, namely, to leave no spaces between your
elements, like this:
<gamedata><word>dog</word><word>snake</word><word>lizard</word></gamedata>
But this is really hard to read and edit. It is much better to put each
element of your XML file on its separate line and use the ignoreWhite
property.
58. Add this ActionScript code after all the existing one:
function parseWords():Void {
if (wordsLoader.firstChild.nodeName == "gamedata") {
var rootNode:XMLNode = wordsLoader.firstChild;
for (i=0; i<rootNode.childNodes.length; i++) {
if (rootNode.childNodes[i].nodeName == "word") {
var currentWord:String = rootNode.childNodes[i].firstChild.nodeValue.toString();
words.push(currentWord);
}
}
}
}
As I mentioned before, the parseWords function will be called
upon once the XML data has been successfully loaded. The first line inside this
function is a conditional if statement:
if (wordsLoader.firstChild.nodeName == "gamedata") {
...which checks to see if the first child of the wordsLoader
XML object is named (nodeName) "gamedata". The first child
of the wordsLoader XML object is indeed named "gamedata". On the
previous page, I have shown you that an XML file can contain only one root node.
The root node is the first child (the first element in the XML file's hierarchy)
of the XML object. In this case, the root node is <gamedata>.
So, there is no need for an if/else conditional statement — an
if condition will do, because Flash will read it and see that it
evaluates as true. So, it will perform all the code within the
conditional statement's curly brackets:
var rootNode:XMLNode = wordsLoader.firstChild;
for (i=0; i<rootNode.childNodes.length; i++) {
if (rootNode.childNodes[i].nodeName == "word") {
var currentWord:String = rootNode.childNodes[i].firstChild.nodeValue.toString();
words.push(currentWord);
}
}
The first line creates the variable rootNode, which is of the
XMLNode type. This variable is created just so that you don't have
to write wordsLoader.firstChild each time (remember,
firstChild is the gamedata root node in this lesson's
example). It is merely a shorthand name.
And then the for loop begins, which is used to read all the
words that will be used in the game and store them in an array:
for (i=0; i<rootNode.childNodes.length; i++) {
if (rootNode.childNodes[i].nodeName == "word") {
var currentWord:String = rootNode.childNodes[i].firstChild.nodeValue.toString();
words.push(currentWord);
}
}
This loop starts with the variable i set to 0 (zero). The loop
will make iterations (i.e. it will repeat itself) as long as its
condition evaluates as true. And it will increase the
value of i with each loop (i++). The condition is that
i must be lesser than the number of the child nodes of the
root node. The number of the child nodes of root node is retrieved by
calling upon childNodes' length property:
i < rootNode.childNodes.length
In this particular example, this means that i must be
lesser than 14. Why? Because there are 14 child nodes inside the
gamedata node:
<?xml version="1.0"?>
<gamedata>
<word>dog</word>
<word>elephant</word>
<word>cat</word>
<word>lion</word>
<word>giraffe</word>
<word>wolf</word>
<word>ostrich</word>
<word>penguin</word>
<word>whale</word>
<word>raccoon</word>
<word>tiger</word>
<word>camel</word>
<word>snake</word>
<word>lizard</word>
</gamedata>
As you can see, each child node of the root node has the name word.
This is used by the if conditional statement contained within the
loop:
if (rootNode.childNodes[i].nodeName == "word") {
var currentWord:String = rootNode.childNodes[i].firstChild.nodeValue.toString();
words.push(currentWord);
}
If the name of the current child node equals "word", the actions inside the
if condition will be performed. Of course, Flash replaces the
construct [i] with the current loop iteration number (0, 1, 2, 3
etc), so that it can check each child node: the first one, second... until the
last one (which is the fourteenth in this case). Since each child node inside
the root one really is named "word", the following two lines
will be executed:
var currentWord:String = rootNode.childNodes[i].firstChild.nodeValue.toString();
words.push(currentWord);
A new variable called currentWord is created and it is of the
String type (meaning it holds a text value). Inside it, the name of
the current child node node will be stored:
rootNode.childNodes[i].firstChild.nodeValue.toString();
As you can see in the ActionScript line above, the toString()
method is used to convert the value of the child element of each root
node's child node to a piece of text. Because this is XML data (nodeValue),
and not text data, it has to be converted to a String so that
you can use it later in the game. If this XML order puzzles you, here's a nice
graph explaining the hierarchy inside the XML object:

Once this value is retrieved and converted to text, it is stored inside the
words array (which you created in the first lines of your code):
words.push(currentWord);
The push method inserts an element to the end of an array. Since
the array is completely empty at the beginning, the first element will be placed
on the first place, the second one after that, etc. So, with each iteration of
the loop, a word pulled out from the words.xml file will be placed
inside the words array. Nice! And easy, as you can see. All you
have to learn to be able to make Flash read data from an XML file is write some
conditional statements and a loop and that's it.
Ok, after Flash has executed this chunk of code, you will have all the words from your XML file at your disposal, neatly stuffed into an array. Let me show you now how you can pull a word at random from this array so that the player has a different word to guess each time she plays the game.
59. Paste this code after the one from the previous section:
function randomize(playAgain):Void {
var randomNumber:Number = random(words.length);
chosenWord = words[randomNumber];
if (playAgain) {
guessWord_txt.text = "";
}
for (var i:Number = 0; i<chosenWord.length; i++) {
guessWord_txt.text = guessWord_txt.text+".";
}
displayedText = _root.guessWord_txt.text;
}
As is obvious from the first line, this function has a parameter passed to
it, playAgain. When you created this variable earlier, you defined
it as a Boolean type of variable, with its initial value set to
false:
var playAgain:Boolean = false;
This is to make possible for different actions to execute, depending whether
the player is playing for the first time, or a subsequent one. Let's see how
this actually works: the function randomize is called only
when the player has clicked the "Play!" button (you will add the code
for this button at the very end of this tutorial). So, suppose the player is
playing the game for the first time. The button is clicked, and the
randomize function is called, with the playAgain parameter
passed to it with its value set to false.
The first line inside the function creates the randomNumber
variable, of the Number type. Its value is a random value, chosen
between zero (the zero itself included) and the number between the parenthesis (words.length).
So, in this example, you have 14 elements inside the words array.
And Flash knows this thanks to the array's length property which
can retrieve it. So, Flash would pick the value like this:
var randomNumber:Number = random(words.length);
randomNumber = random(14);
So a random value is chosen between 0 and 13. Next, from this same array (words),
the word corresponding to this random number is chosen:
chosenWord = words[randomNumber];
Flash reads the randomNumber variable's value and
searches for the element with that position inside the words array,
and stores it inside the chosenWord variable.
Elements of an array have numbered positions, starting from zero, like this:

Next, Flash checks if the value of the playAgain variable is set
to true:
if (playAgain) {
guessWord_txt.text = "";
}
And if it is, the text field which displays the letters the player has
guessed is emptied from any text. Why? Because if playAgain equals
true, it means the player has pressed the "Play!" button again and the game is
started again. And it is logical that if it is going to be played again, that
the text field has to be empty again.
After that, the following code is executed, no matter if the playAgain
variable equals true or false:
for (var i:Number = 0; i<chosenWord.length;
i++) {
guessWord_txt.text = guessWord_txt.text+".";
}
displayedText = _root.guessWord_txt.text;
This is a familiar for loop. The condition for the loop to exit
is that i must be lesser than the number of characters
of the word stored inside the chosenWord String variable. Let's say
for example that the word "lion" was the one randomly picked from the
words array. It has 4 characters (letters) inside it: lion. So, the loop
will go from 0 to 3. Once it reaches 4, it will break and stop executing the
code inside itself. And this code says the following:
guessWord_txt.text = guessWord_txt.text+".";
The text shown inside the guessWord_txt text field equals the
text already found in it, with a dot (.) added to its end. So, in
the case the word "lion" was picked, the for loop will make 4 iterations, and
the following would be seen by the player in the text field: ....
Four dots, that's right. If you don't like the dots (which represent the letters of the hidden word), you can put a question mark (?) or any character that you deem appropriate. The loop goes like this: the first time, there is nothing displayed in the text field, so:
guessWord_txt.text = guessWord_txt.text+".";
guessWord_txt.text = "" + ".";
guessWord_txt.text = ".";
During the second loop, it goes like this:
guessWord_txt.text = guessWord_txt.text+".";
guessWord_txt.text = "." + ".";
guessWord_txt.text = "..";
etc.
And so on, until you get 4 dots displayed. Next comes the line of ActionScript code that comes after the loop:
displayedText = _root.guessWord_txt.text;
The text that is displayed inside the guessWord_txt field on the
stage (i.e. the dots representing the hidden word) is stored inside the
displayedText variable which you defined earlier.
This variable will be used to store the letters guessed by the player along with
the dots, so that the proper thing can be displayed and
compared to the complete hidden word (you will see how this comparison is done
later).
60. Paste this ActionScript code right after the one inserted so far:
function placeLetters():Void {
this.createEmptyMovieClip("allLetters_mc", 1);
allLetters_mc._y = 300;
allLetters_mc._x = 20;
for (var i:Number = 0; i<alphabet.length; i++) {
var newLetter:MovieClip = allLetters_mc.attachMovie("letterButton", "letter"+alphabet.charAt(i),
i);
newLetter.letter_txt.text = alphabet.charAt(i);
if (i<8) {
newLetter._y = 0;
newLetter._x = i*40;
} else if (i>=8 && i<16) {
newLetter._y = 40;
newLetter._x = (i-8)*40;
} else if (i>=16) {
newLetter._y = 80;
newLetter._x = (i-16)*40;
}
newLetter.onRelease = function() {
var matchFound:Boolean = false;
var clickedLetter:String = this._name.charAt(this._name.length-1);
for (var j:Number = 0; j<chosenWord.length; j++) {
if (chosenWord.charAt(j) == clickedLetter) {
_root.guessWord_txt.text = displayedText.substr(0, j)+clickedLetter+displayedText.substr((j+1));
matchFound = true;
this._visible = false;
}
displayedText = _root.guessWord_txt.text;
}
if (displayedText == chosenWord) {
endOfGame(true);
}
if (matchFound == false) {
this._visible = false;
_root.hangman_mc.nextFrame();
if (hangman_mc._currentframe == 10) {
endOfGame(false);
}
}
};
}
}
Now that is one loooong function! Don't be afraid of it :). I will show you step by step what each of this function's parts does and how it works. Before starting, just know that this function is also called once the player has pressed the "Play!" button.
The first code inside the function that gets executed are three lines:
this.createEmptyMovieClip("allLetters_mc", 1);
allLetters_mc._y = 300;
allLetters_mc._x = 20;
The first one creates a new movie clip from scratch. The
keyword this means that the movie clip will be created on the main
or _root timeline, since the keyword itself resides inside the
placeLetters function which is placed on the main timeline.
The createEmptyMovieClip command creates, well, an empty movie
clip :). It has two parameters which must be defined: the
Instance name of the new movie clip called allLetters_mc
(without it, you wouldn't be able to do anything with it) and the depth
at which it is stored. The depth is like a third imaginary dimension on the
computer's screen. The higher the number, the more "closer to you" and further
"away from the screen" the movie clip will be placed. The main timeline is on
depth 0 (zero). So by choosing 1 as depth value fro your new movie clip is fine.
The next two lines place this new movie clip on new coordinates
— 300 pixels from the top of the stage (_y = 300) and 20 pixels to
the right of the stage's left edge (_x = 20). You have to move this
movie clip so that its contents (which will come in a moment) do not overlap
with the main text field (guessWord_txt).
Now comes the main for loop which makes up the
biggest part of the placeLetters function. Everything except the
above three lines of code is placed inside it.
for (var i:Number = 0; i<alphabet.length; i++) {
Just as the previous for loops, this one starts with i
set to zero, which is incremented by 1 at each pass of the loop. The condition
that must be fulfilled in order for the loop to exist is that i
must be lesser than the number of characters found in the alphabet
variable. As you remember, you made this variable at the beginning,
like this:
var alphabet:String = "abcdefghijklmnopqrstuvwxyz";
This is a String (text) variable, which holds inside all the letters of the English alphabet. So the loop will make as many iterations as there are letters in the alphabet (26). This makes perfect sense, because you must write the code that will place a button for each alphabet letter on the stage.
And here is the code that places the letter buttons on the stage:
var newLetter:MovieClip = allLetters_mc.attachMovie("letterButton",
"letter"+alphabet.charAt(i), i);
newLetter.letter_txt.text = alphabet.charAt(i);
if (i<8) {
newLetter._y = 0;
newLetter._x = i*40;
} else if (i>=8 && i<16) {
newLetter._y = 40;
newLetter._x = (i-8)*40;
} else if (i>=16) {
newLetter._y = 80;
newLetter._x = (i-16)*40;
}
The first line serves attaches a movie clip dynamically from the Library onto the stage:
var newLetter:MovieClip = allLetters_mc.attachMovie("letterButton", "letter"+alphabet.charAt(i), i);
On the left side of the assignment operator (=)
is the already familiar variable definition which is here, of course, of the
MovieClip type. Then, you tell Flash to attach a movie clip from
the Library to the empty movie clip that you have just made previously (allLetters_mc.attachMovie).
This is done by first stating the Identifier name of the movie
clip in the Library: letterButton in this case. You have defined
this identifier when you created the small movie clip before. It is the one with
the small dynamic text field inside. Here is the image of this movie clip, to
avoid any confusion:
![]()
After that comes the new Instance name of the movie clip,
created dynamically: "letter"+alphabet.charAt(i). This must be done
like this in order to have a different Instance name for each
letter button. Since the main loop makes as many passes as there are letters in
the English alphabet (26), each movie clip attached from the Library will have a
unique name, associated with the letter it represents. At the first iteration of
the loop, when i equals zero, you will obtain the following result:
"letter"+alphabet.charAt(i)
"letter"+a
lettera
Then letterb, letterc, etc. This is thanks to the
charAt() method of the String object. The variable alphabet
(which contains all the letters of the alphabet) is a String. The
charAt() method finds and reads the character situated at the position
written between the parenthesis. In this case, this is i,
meaning it is different at each iteration of the loop — so every letter of the
alphabet will be read and the unique Instance name made from it.
![]()
The last parameter of the attachMovie() method
is the depth of the movie clip pulled from the Library. This is
again the variable i. This tells you that the depth of each movie
clip will be unique. Which is excellent, because if you'd attach each movie clip
on the same depth level, the previous one would get erased.
There can be only one movie clip instance present on each depth level, on the
location where you are attaching them. In this exercice, you
are attaching all these movie clips inside the allLetters_mc movie
clip which was made from scratch. Inside it, you can place as many movie clips
as you like, as long as each one of them has its own unique depth level. But,
imagine that you had another movie clip which would get attached ones from the
Library. In it, you could again attach them using the same depth levels (0, 1,
2, 3, etc) because this would have no influence whatsoever on the first movie
clip. Each movie clip is like a small world which can within itself host many
other movie clips.
OK. During each iteration of the loop, a movie clip gets attached and
receives its unique Instance name. And it is stored inside the
newLetter variable. This is done so that during each iteration
you can just reference this newly attached movie clip by telling Flash
newLetter, instead of typing the whole thing, which is different each
time. This simplifies your ActionScript coding greatly and makes life a lot more
easier.
The next line makes the appropriate letter appear in the dynamic
letter_txt text field inside each movie clip:
newLetter.letter_txt.text = alphabet.charAt(i);
Now comes an if/else if conditional statement:
if (i<8) {
newLetter._y = 0;
newLetter._x = i*40;
} else if (i>=8 && i<16) {
newLetter._y = 40;
newLetter._x = (i-8)*40;
} else if (i>=16) {
newLetter._y = 80;
newLetter._x = (i-16)*40;
}
This one serves to place the letter buttons (they act as buttons, but they
are movie clip symbols, of course) on the stage in three separate rows. The
first eight buttons (i<8) will be placed in the first row:
if (i<8) {
newLetter._y = 0;
newLetter._x = i*40;
That's because the _y property (vertical position) is the same:
0. The horizontal coordinate (_x) is always different: it is
the result of i (0, 1, 2, 3, etc) being
multiplied by 40. Why 40? Because the letter button movie clip
which gets attached from the Library is 31 pixels wide. So by choosing 40 you
leave 9 pixels of space between each button. The next portion of letters (i>=8
&& i<16) goes in the second row, below the first one, by setting the
_y property of each movie clip here to 40:
} else if (i>=8 && i<16) {
newLetter._y = 40;
newLetter._x = (i-8)*40;
The _x property is made by first substracting 8
from i and then multiplying the result by 40. If
you don't substract this, the movie clips would be placed further to the right,
away from the first row.
And here's the rest, following the same placement principles:
} else if (i>=16) {
newLetter._y = 80;
newLetter._x = (i-16)*40;
}
Thanks to the if conditional statement, the final result looks
like this:

Let me show you now how the buttons are made clickable via ActionScript (you already pasted this code, don't do it again :)):
newLetter.onRelease = function() {
var matchFound:Boolean = false;
var clickedLetter:String = this._name.charAt(this._name.length-1);
for (var j:Number = 0; j<chosenWord.length; j++) {
if (chosenWord.charAt(j) == clickedLetter) {
_root.guessWord_txt.text = displayedText.substr(0, j)+clickedLetter+displayedText.substr((j+1));
matchFound = true;
this._visible = false;
}
displayedText = _root.guessWord_txt.text;
}
if (displayedText == chosenWord) {
endOfGame(true);
}
if (matchFound == false) {
this._visible = false;
_root.hangman_mc.nextFrame();
if (hangman_mc._currentframe == 10) {
endOfGame(false);
}
}
};
As you can see, all the function's code is included within each attached
movie clip's onRelease event. This event happens
when the player press and releases the mouse button over a
movie clip. If you want, you can replace this with the onPress
event, which happens the instant the mouse button is pressed over the movie
clip. But this latter event is best used when something has to happen quick,
like a spaceship firing a shot in a shoot 'em up kind of game.
Inside the function, the first two lines are these:
var matchFound:Boolean = false;
var clickedLetter:String = this._name.charAt(this._name.length-1);
First, the matchFound variable is created, which will be later
used to check if the player has clicked on a letter that is inside the hidden
word. It is set to false at the beginning. Now you have to make
Flash know which letter the player has clicked. To do this, you have to create a
String variable which will store the clicked letter:
var clickedLetter:String. After that, you retrieve the clicked
letter from the movie clip's Instance name:
this._name.charAt(this._name.length-1)
The construct this._name refers to the Instance name of the
movie clip that has been clicked. The ActionScript keyword this
refers to the clicked movie clip because it is placed inside its
onRelease event handler. After that, you use the charAt()
method to extract the appropriate character/letter. Suppose the current movie
clip is for example buttone. Flash would extract the letter e
like this:
this._name.charAt(this.name.length - 1)
this._name.charAt("lettere".length - 1)
this._name.charAt(7 - 1)
this._name.charAt(6)
e
The length of the Instance name lettere is 7
characters. The first character in a string always has the position set
to 0 (zero). That's why by substracting 1 from 7 you get 6, which is
the position of the last character in the string, which is e in
this case. And that character gets stored inside the clickedLetter
variable.
Now comes a new for loop:
for (var j:Number = 0; j<chosenWord.length; j++) {
if (chosenWord.charAt(j) == clickedLetter) {
_root.guessWord_txt.text = displayedText.substr(0, j)+clickedLetter+displayedText.substr((j+1));
matchFound = true;
this._visible = false;
}
displayedText = _root.guessWord_txt.text;
}
Here, a new variable, j, is used, to avoid any conflict with the
previous i in the main loop. It is this for loop that
is checking if the clicked letter can be found anywhere in the hidden
word that has to be guessed. To accomplish that, the loop must
pass through all the letters of the word (to be programatically
correct, all the characters of the string). That's why the condition of the loop
is: j < chosenWord.length. The variable j will
increase until it reaches the length (of characters) of the hidden word, the one
that is stored inside the chosenWord varaible.
The loop checks if the clicked letter is inside the hidden word with the help
of an if conditional statement:
if (chosenWord.charAt(j) == clickedLetter) {
This literally tells Flash:
if (the character at position j inside the string chosenWord
equals the clickedLetter) {
...execute the following actions...
}
REMEMBER The equality operator (==) checks if two values are equal, while the assignment operator (=) is used to assign values to variables.
And this check is done for each character of the string
stored in the chosenWord variable. If a match is found,
the following three lines of code get executed:
_root.guessWord_txt.text = displayedText.substr(0, j)+clickedLetter+displayedText.substr((j+1));
matchFound = true;
this._visible = false;
The left side of the first line clearly tells you that you are commanding
Flash to display some text in the guessWord_txt text field.
And what will be displayed? The found letter (if the player
guessed correctly), along with the all the other hidden letters,
that are represented by dots (or question marks, if you decided so), that have
yet to be guessed:
displayedText.substr(0, j)+clickedLetter+displayedText.substr((j+1));
On the previous page, you have set the value of the displayedText
variable to dots only — the number of which equals the number of the letters
inside the hidden word. Suppose the hidden word that has to be guessed is
"penguin". This word is composed of 7 letters, so in this case the value
of displayedText variable would be ".......". Also, suppose that
the player has clicked on the letter g.
The loop would begin, making 3 iterations without finding a match. On the
fourth iteration, the match would be found, because the letter g is on the
position number 3 inside the word "penguin" (remember, the characters in a
string are numbered beginning from zero, that's why the fourth position
in a string equals number 3). The if condition
would evaluate as true, and the code inside it would execute,
and Flash would interpret like this:
displayedText.substr(0, j) + clickedLetter +
displayedText.substr((j+1))
".......".substr(0, 3) + "g" + "......." .substr((3+1))
"..." + "g" + "..."
"...g..."
And that's what would the user see appear in the text field. Let me explain
you this string manipulation in more detail. The substr() method of
the String object does this: it extracts a substring from a string
(i.e. a part of text), based on the starting position and length
that you provided. The easiest way to understand this is by seeing an actual
example.
Let's say that the word you are tinkering with is "computer", and that you wanted to extract the first three letters from it. You would do it like this:
var myText:String = "computer";
var myChunk:String = myText.substr(0, 3);
The value of the myChunk variable would be "com",
which are indeed the first three characters inside the myText
string. So, the first parameter between the parenthesis is the
starting place inside the string, where the extraction will
begin. The second parameter is the length of
the string that you want to extract, including the first character.
Here is a nice visual representation of that:

If you wanted to extract the text "mput", you would write
substr(2, 4), because the letter m is situated at position 2
and the length of the string that you want to extract is 4. Allright!!! :-)
In the actual mechanism that writes the guessed letter along with the dots, you use this simple but very useful method to extract the first part of the word (represented by dots), before the guessed character:
displayedText.substr(0, j)
...after which you add the guessed character:
displayedText.substr(0, j) + clickedLetter
...and then you add the remaining part of the word, represented by dots, because those letters haven't been guessed yet:
displayedText.substr(0, j) + clickedLetter + displayedText.substr((j+1))
You have certainly noticed that the substr() method is used
differently in this last part. There is no second parameter
here: displayedText.substr((j+1)). The first one is the point where
the extraction will start. And since the second one (length) is omitted, Flash
will automatically pick all the characters that are found after the
starting point. The starting point is exactly the character
after the guessed one: j+1. In this way, the rest of the
word is extracted.
Finally (whew! :-)), the lines that get executed after this string manipulation is over are:
matchFound = true;
this._visible = false;
The variable matchFound is set to true so that
you can later tell Flash not to advance the hangman animation,
because the player has actually guessed a letter. And the line
this._visible = false hides the clicked letter. You must
do this, whether the user has guessed the letter or not. You can't be cruel and
make the player commit the same mistake twice, possibly. All the letters that
are clicked must be eliminated, leaving only the ones that haven't been tried by
the player.
And after the if conditional statement, no matter if a matching
letter was found or not, the displayedText variable has to be
updated:
displayedText = _root.guessWord_txt.text;
It will now reflect the current state of the
guessWord_txt text field, with both the hidden and revealed letters. This
is done so that a proper check can be made, to see if the whole word was
guessed by the player. And that's precisely what comes next:
if (displayedText == chosenWord) {
endOfGame(true);
}
This simple if statement checks to see if the string inside the
displayedText variable matches the one stored in the
chosenWord variable. If it does, the endOfGame() function is
called, with a Boolean true parameter passed to it, signaling that
the player has won the game. That function comes later in the
code, so I will not explain it now.
And what if the player clicked a letter that isn't found in the hidden word?
Then the matchFound variable stays false. And the
following code will be executed (you already entered it, as a part of the movie
clip's onRelease event, remember):
if (matchFound == false) {
this._visible = false;
_root.hangman_mc.nextFrame();
if (hangman_mc._currentframe == 10) {
endOfGame(false);
}
}
As is clear from the first line, this is an if statement that
checks if the matchFound variable equals false. If
it doesn't, it gets completely ignored, along with all the code placed inside
it. But since I am explaining here what happens when the player clicked the
wrong letter, I will tell you what happens when matchFound really
does equal false.
The first line of code that is run is the one that hides the clicked letter movie clip:
this._visible = false;
Remember, the letter the player has clicked has to be hidden, whether it was
a good or a bad guess. And now you have to show the player that she or
he made a mistake: the hangman must begin to appear. This is done by
advancing the animation inside the hangman_mc movie clip by
one frame:
_root.hangman_mc.nextFrame();
And you also have to make Flash check if the animation arrived at the end, in the case the player has made all the mistakes she could and the game is over:
if (hangman_mc._currentframe == 10) {
endOfGame(false);
}
If the current frame of the hangman_mc movie clip is the tenth
frame (hangman_mc._currentframe == 10), the endOfGame()
function will be called, but this time with the parameter passed to it
set to false, signaling that the game is over
and that the player didn't succeed in guessing the hidden word.
I have made this game to end after ten wrong guesses, but of course, you can give more chances to the player if you wish so. Just remember that your hangman animation has to have the same number of frames as there are wrong guesses that a player can make. The animation must be more complex, too: you must add more elements that will appear as a wrong guess is made: the eyes, nose and mouth appearing for each bad guess, or maybe fingers on a hand. Simply decide what looks best for your game.
61. Add this code to the one already inserted:
function endOfGame(success:Boolean) {
allLetters_mc.removeMovieClip();
startScreen_mc._visible = true;
if (success) {
startScreen_mc.message_txt.text = "Congratulations! You did
it! Want to try again? Press the play button below.";
} else {
startScreen_mc.message_txt.text = "GAME OVER! Aaargh! You
killed the little guy! Want to try again? Press the play button below.";
}
playAgain = true;
}
The function endOfGame() governs what will be displayed
on the screen that will appear at the end of a game, whether the player
succeeded in guessing the word or not. This function has a parameter passed to
it, which is a Boolean value — it can either be true or
false.
The first two lines of code that are being executed upon function's execution do so no matter if the parameter turned out as true or false:
allLetters_mc.removeMovieClip();
startScreen_mc._visible = true;
The first one removes all the letter buttons. These buttons
are the movie clips that were attached dynamically from the Library inside the
allLetters_mc movie clip. So by removing this movie clip with the
removeMovieClip() method you are effectively removing all the
buttons with it.
The second line makes the startScreen_mc movie clip
appear by setting its _visible property to true.
This movie clip contains the text field that displays the welcome message at the
start of a game and the resulting message at the end of a game. Also, the
"Play!" button is situated inside it.
And now comes the if conditional statement which decides
what will be shown as the message, depending on player's success in
guessing the hidden word:
if (success) {
startScreen_mc.message_txt.text = "Congratulations! You did
it! Want to try again? Press the play button below.";
} else {
startScreen_mc.message_txt.text = "GAME OVER! Aaargh! You
killed the little guy! Want to try again? Press the play button below.";
}
The construct if(success) has the same exact
functionality as if you had written if(success == true).
The former one is a shorthand version. Why write more code if you can make it
more compact? So, if the player guessed the word correctly (success),
the following ActionScript code will be executed:
startScreen_mc.message_txt.text = "Congratulations! You did it! Want to try again? Press the play button below.";
It is a simple command that tells Flash what to display in the
message_txt text field (placed inside the startScreen_mc
movie clip). Just remember that the message must be included between the
quotation marks.
On the other hand, if the player failed to guess the hidden word picked at
random, the if part of the conditional will be ignored, and
the else portion will be executed:
startScreen_mc.message_txt.text = "GAME OVER! Aaargh! You killed the little guy! Want to try again? Press the play button below.";
Again, the same text field is referenced, but with a different message.
The endOfGame() function contains one more bit of code that will
be executed always, because it is outside the if conditional construct:
playAgain = true;
The variable playAgain is set to true (remember, it
is defined as false at the very start of the code), indicating to
Flash that the player isn't playing for the first time. Thanks to this, if the
player begins a new game, Flash will erase the text that stayed in the main text
field from the previous game. I explained that bit before, when showing you the
inner workings of the the randomize() function. The code that
resets the text field to its initial state is shown in bold:
function randomize(playAgain):Void {
var randomNumber:Number = random(words.length);
chosenWord = words[randomNumber];
if (playAgain) {
guessWord_txt.text = "";
}
for (var i:Number = 0; i<chosenWord.length; i++) {
guessWord_txt.text = guessWord_txt.text+".";
}
displayedText = _root.guessWord_txt.text;
}
62. At last, add the final chunk of ActionScript code:
startScreen_mc.play_mc.onRelease = function() {
this._parent._visible = false;
guessWord_txt._visible = true;
hangman_mc.gotoAndStop(1);
randomize(playAgain);
placeLetters();
};
This is the Play! button's onRelease event handler
function. It tells Flash what to do when the player has clicked the
button, as for the first time when the game is played, as well as for all the
subsequent rounds. The five lines of code included do the following:
The first one hides the startScreen_mc movie clip:
this._parent._visible = false;
The construct this._parent points to the startScreen_mc
movie clip. Since it is placed inside the play_mc movie clip's
onRelease event, the keyword this points to
the play_mc movie clip itself. And the keyword
_parent denotes its parent movie clip (the one which hosts
it) — startScreen_mc.
The main text field is made visible again:
guessWord_txt._visible = true;
And the hangman_mc movie clip is sent back to the first
frame, which is empty:
hangman_mc.gotoAndStop(1);
You must do this, because at the start of a new game, no part of the hanging animation can be visible — no potential wrong guesses have been made yet.
A new word is picked at random, by calling the
randomize() function:
randomize(playAgain);
This is done so that the game can start with a new word.
NOTE Although a new word will be picked at random each time the hangman game is started, chances are that the same word could appear. This is not because of Flash, but because of the law of probability. So, the more words you insert in your XML file, the lesser the chance of the same word appearing again. ActionScript code could be written for creating a mechanism that would eliminate a word that has already been guessed, but I will leave that for some other occasion :).
And as the last action, the placeLetters() function is called,
to create the allLetters_mc movie clip anew and attach all
the letter buttons dynamically again:
placeLetters();
The first fact that I want to tell you is that this hangman game (the final SWF file) has a size of only 3 KB! That's pretty cool! Both the XML and TXT files are so small in size that the whole game loads almost instantly.
You saw how ActionScript helps to streamline tasks that would require too much time to create manually, like the creation of all the alphabet letters' buttons. Also, like I said before, this Flash game is completely dynamic because once the SWF is finalized, all you have to do to modify the game is change the data in the XML and TXT files.
As for the animation of the hanging, you can make it more complex, even add sound — this is just a question of much time and effort you are willing to put into it.
Pay attention to one important detail: this game supports only one-word guesses. You cannot insert two words inside any of the XML elements (for example: <word>two words</word>), because the code in this lesson isn't created to handle non-breaking spaces. However, you have learned a lot and I am sure that you will figure this out by yourself, if you wish to insert this capability into your hangman game.