Creating a dynamic hangman game in Flash 8 with XML and ActionScript – part 4 of 4
Continuing from the third page of the hangman game lesson, you will now…
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
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.
Using ActionScript to find a matching letter inside a word
Now comes a new for
loop:
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;
}
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…
}
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.
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
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
guessWord_txt.text = guessWord_txt.text+".";
}
displayedText = _root.guessWord_txt.text;
}
Creating the code that powers the Play! button
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.
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();
Conclusion
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:
Download all the source files here
Return to the first page of the ActionScript hangman game and leave a comment.