Creating a dynamic hangman game in Flash 8 with XML and ActionScript – part 3 of 4
Making a randomizing function with ActionScript
So, continuing from the second page of the ActionScript hangman lesson, you shall now:
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
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
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).
Fiiine! You’ll see now how to create the biggest function in this project, which will place the letter buttons on the stage, define their clickability and much, much more. Onwards!
ActionScript code that makes up the main hangman game functionality
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
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
_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 = 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
).
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 Just as the previous 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); 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 ( After that comes the new Instance name of the movie clip, created dynamically: "letter"+alphabet.charAt(i) Then The last parameter of the OK. During each iteration of the loop, a movie clip gets attached and receives its unique newLetter.letter_txt.text = alphabet.charAt(i); Now comes an if (i<8) { This one serves to place the letter buttons (they act as buttons, but they are movie clip if (i<8) { That’s because the 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 ( } else if (i>=8 && i<16) { The } else if (i>=16) { Thanks to the Please proceed to the fourth and final page of this lesson to see how to make the buttons clickable.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:
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;
}=
) 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:"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"+a
letteraletterb
, 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.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.
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:if/else if
conditional statement:
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;
}
symbols, of course) on the stage in three separate rows. The first eight buttons (i<8
) will be placed in the first row:
newLetter._y = 0;
newLetter._x = i*40;_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? 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:
newLetter._y = 40;
newLetter._x = (i-8)*40;_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:
newLetter._y = 80;
newLetter._x = (i-16)*40;
}if
conditional statement, the final result looks like this: