ActionScript code that makes up the main hangman game functionality
// Section 4
function placeLetters():Void {
this.createEmptyMovieClip("allLetters_mc", 1);
allLetters_mc._y = 400;
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<13) {
newLetter._y
= 0;
newLetter._x
= i*35;
} else {
newLetter._y
= 35;
newLetter._x
= (i-13)*35;
}
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.
Creating a new movie clip instance from scratch
The first code inside the function that gets executed are three lines:
this.createEmptyMovieClip("allLetters_mc",
1);
allLetters_mc._y = 400;
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
— 400 pixels from the top of the stage (_y
= 400) 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).
Placing the letter buttons on the stage
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<13) {
newLetter._y
= 0;
newLetter._x
= i*35;
} else {
newLetter._y
= 35;
newLetter._x
= (i-13)*35;
}
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
exercise, 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<13) {
newLetter._y
= 0;
newLetter._x
= i*35;
} else {
newLetter._y
= 35;
newLetter._x
= (i-13)*35;
}
This one serves to place the letter
buttons (they act as buttons, but they
are movie clip symbols, of course) on
the stage in two separate rows. The
first 13 buttons (i<13)
will be placed in the first row:
if (i<13) {
newLetter._y
= 0;
newLetter._x
= i*35;
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
35. Why 35? Because the
letter button movie clip which gets
attached from the Library is 31 pixels
wide. So by choosing 35 you leave 4
pixels of space between each button. The
next portion of letters (i>=13)
goes in the second row, below the first
one, by setting the _y
property of each movie clip here to 35:
} else {
newLetter._y
= 35;
newLetter._x
= (i-13)*35;
The _x property is made
by first substracting 13
from i and then
multiplying the result by 35.
If you don’t subtract this, the movie
clips would be placed further to the
right, away from the first row.
Thanks to the if
conditional statement, the final result
looks like this:

Making the buttons clickable
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 quickly, 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.
Using ActionScript to find a matching letter inside a word
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…
}
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.
Advancing the animation of the hangman if a wrong guess was made
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.
Scripting the results that will be displayed at the end of the game
// Section 5
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;
}
Creating the code that powers the Play! button
// Section 6
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.
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();
Test your Movie
Your movie is now ready to run! Make sure you are not in symbol editing mode (return to Scene 1 if you are) and press Ctrl-Enter to test your movie ;>)
Your movie may be working, but it has a couple of weaknesses:
1) If you fail to guess the word the movie does not reveal the correct word. Can you modify the code so that the missing letters are revealed?
2) In the previous pages we have defined the mystery words to be used in the game within the ActionScript code, using the following line:
words = ["dog", "elephant", "cat", "giraffe", "lion", "wolf", "ostrich", "penguin", "whale", "raccoon", "tiger", "snake", "lizard"];
This is neat enough, but it means that if we want to modify the list of words we have to open up the FLA file in Flash and modify it there - this might be difficult for some people and it will be impossible if they have only the SWF and not the FLA file. So it would be much better if the word list could be stored in a separate file that could be easily modified using NotePad or Word, for example. Click HERE to move to the next page where you will learn how this can be done.
